I work with Java/ Spring MVC RESTful
app and get 400 HTTP status error
while doing a POST
request. The @RestController
method is provided,
@RequestMapping(value = "/generateAddress", method = RequestMethod.POST)
public ResponseEntity<WalletInfoWrapper> generateAddress(@RequestParam("walletName") String walletName,
@RequestParam("currencyName") String currencyName) {
logger.info("walletName {} and currencyName {}", walletName, currencyName);
// return if the wallet name or the currency is null
if (Objects.isNull(walletName) || Objects.isNull(currencyName)) {
return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
}
WalletInfo walletInfo = walletService.generateAddress(walletName, currencyName);
if (Objects.isNull(walletInfo)) {
return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
}
WalletInfoWrapper walletInfoWrapper = new WalletInfoWrapper();
walletInfoWrapper.setName(walletInfo.getName());
return new ResponseEntity<WalletInfoWrapper>(walletInfoWrapper, HttpStatus.CREATED);
}
The POST
request in the Postman
provided below,
The error message informs, Required String parameter 'walletName' is not present
I can also provide the code for the services
and the dataase
layers for observing the drop-down operations. What is the issue here?
UPDATE
I updated the Postman
request like this and still having the same error,
UPDATE 1
I still have the same issue,
I POST
with the data,
{"walletName":"puut","currencyName":"Bitcoin"}
The code is provided below,
@RequestMapping(value = "/generateAddress", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<WalletInfoWrapper> generateAddress(@RequestBody WalletWithMoneyRequest walletWithMoneyRequest) {
String walletName = walletWithMoneyRequest.getWalletName();
String currencyName = walletWithMoneyRequest.getCurrencyName();
logger.info("walletName {} and currencyName {}", walletName, currencyName);
// return if the wallet name or the currency is null
if (Objects.isNull(walletName) || Objects.isNull(currencyName)) {
return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
}
WalletInfo walletInfo = walletService.generateAddress(walletName, currencyName);
if (Objects.isNull(walletInfo)) {
return new ResponseEntity<WalletInfoWrapper>(HttpStatus.NOT_ACCEPTABLE);
}
WalletInfoWrapper walletInfoWrapper = new WalletInfoWrapper();
walletInfoWrapper.setName(walletInfo.getName());
return new ResponseEntity<WalletInfoWrapper>(walletInfoWrapper, HttpStatus.CREATED);
}
The POJO
is provided,
private class WalletWithMoneyRequest {
String walletName;
String currencyName;
public WalletWithMoneyRequest(String walletName, String currencyName) {
this.walletName = walletName;
this.currencyName = currencyName;
}
public WalletWithMoneyRequest() {
}
public String getWalletName() {
return walletName;
}
public String getCurrencyName() {
return currencyName;
}
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
public void setWalletName(String walletName) {
this.walletName = walletName;
}
}
This is the error message,
Here ia the Tomcat server info,
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver: 08/19/2017 19:45:55 - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `mobi.puut.controllers.WalletRestController$WalletWithMoneyRequest` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `mobi.puut.controllers.WalletRestController$WalletWithMoneyRequest` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor
at [Source: (PushbackInputStream); line: 1, column: 2]
Tomcat Localhost log
Tomcat Catalina log
Edit
In your Postman request, instead of sending JSON, send the values as x-www-form-urlencoded
.
Your controller is expecting 2 request parameters that normally look like this: /someurl?walletName=my-wallets-name¤cyName=dollars.
You're sending a json string in the post body, but no formal parameters. You need to update either your POST, or your controller to make the two ends agree. I think you probably want to replace the two @RequestParam annotated Strings, with a Java pojo that has two String members: walletName and currencyName, drop that pojo in your request method as an argument and precede it with the annotation @RequestBody. This will match your json post.
To have your controller accept the post with JSON in the body edit it like this:
@RequestMapping(value = "/generateAddress", method = RequestMethod.POST)
public ResponseEntity<WalletInfoWrapper> generateAddress(@RequestBody
WalletWithMoneyRequest myJsonRequestComingIn) {
logger.info("walletName {} and currencyName {}", myJsonRequestComingIn.getWalletName(), myJsonRequestComingIn.getCurrencyName());
And your pojo
public class WalletWithMoneyRequest{
private String walletName;
private String currencyName;
//getters and setters down here.
To elaborate on zerpsed's answer.
Change the signature to:
public ResponseEntity<WalletInfoWrapper> generateAddress(@ResponseBody WalletPOJO walletCurrency)
Where the WalletPOJO has the two fields walletName and currencyName
I believe the issue is solved for now. I have used a POJO
as suggested with the @RequestBody
parameter in the RESTful
method. The catch here is I need to make the POJO
out of the class (in the same file though) and later, put in the entity directory as an entity.
class WalletWithMoneyRequest {
String walletName;
String currencyName;
public WalletWithMoneyRequest(String walletName, String currencyName) {
this.walletName = walletName;
this.currencyName = currencyName;
}
public WalletWithMoneyRequest() {
}
public String getWalletName() {
return walletName;
}
public String getCurrencyName() {
return currencyName;
}
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
public void setWalletName(String walletName) {
this.walletName = walletName;
}
}
The main issue is believe was an error in the HQL
,
I wrote currency =: currency
where it should be currency = :currency
I still can't have the data in the database as I will need to modify the method in the database
layer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With