org.springframework.web.bind.MissingServletRequestParameterException - java

Facing issue while posting call to server side
Exception stack trace :
"org.springframework.web.bind.MissingServletRequestParameterException: Required int parameter 'answerId' is not present\r\n\tat org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.raiseMissingParameterException(AnnotationMethodHandlerAdapter.java:773)\r\n\tat org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestParam(HandlerMethodInvoker.java:509)
Javascript call in controller.js
$scope.saveCorrectAnswer = function(answerId) {
var answerIdVal = 0;
answerIdVal = answerId;
if(document.getElementById(answerId).className == 'ico-white-check') {
$scope.answer.correct = 'Y';
} else{
$scope.answer.correct = 'N';
}
Answer.update({answerId: answerIdVal, correct: $scope.answer.correct}, function(response) {
// On success go to Exchange
//$route.reload();
},
Mapping in service controller in java:
#RequestMapping(method = RequestMethod.PUT, consumes = "application/json", produces = "application/json")
#ResponseBody
public void addCorrectAnswer(#RequestParam int answerId, #RequestParam String correct) {
getAnswerDAC().addCorrectAnswer(answerId, correct);
}

#RequestParam has an attribute required which is true by default. If answerId is not required, change the annotation and parameter type as follows...
#RequestMapping(method = RequestMethod.PUT, consumes = "application/json", produces = "application/json")
#ResponseBody
public void addCorrectAnswer(#RequestParam(required = false) Integer answerId, #RequestParam String correct) {
getAnswerDAC().addCorrectAnswer(answerId, correct);
}
Edit: Since answerId is a primitive value in your example, you would also need to provide a defaultValue in the annotation. Providing a defaultValue implicitly sets required to false, so I'll leave it out of the example...
#RequestMapping(method = RequestMethod.PUT, consumes = "application/json", produces = "application/json")
#ResponseBody
public void addCorrectAnswer(#RequestParam(defaultValue = 0) int answerId, #RequestParam String correct) {
getAnswerDAC().addCorrectAnswer(answerId, correct);
}
Hope this helps

Related

How Do I Mark A RequestParam As Optional In Swagger?

I am generating the swagger docs for my REST API using SpringFox.
I have added an optional parameter to my API now:
#ApiOperation(
value = "Get all cars"
)
#GetMapping(value = "/cars", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseDTO<CarDTO>> getCars(
#RequestParam(defaultValue = "1") Integer page,
#RequestParam(required = false) String status) {
ResponseDTO<CarDTO> response = service.getCars(page, status);
return ResponseEntity.ok(response);
}
How do I highlight in the swagger docs that one is required and the other is optional?
You have the #ApiParam annotation you can use, it has a property required which you can put to true or false depending on your needs
#ApiOperation(
value = "Get all cars"
)
#GetMapping(value = "/cars", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseDTO<CarDTO>> getCars(
#ApiParam(required = true) #RequestParam(defaultValue = "1") Integer page,
#ApiParam(required = false) #RequestParam(required = false) String status) {
ResponseDTO<CarDTO> response = service.getCars(page, status);
return ResponseEntity.ok(response);
}
As you can see in the documentation, it has other properties like
access
allowableValues
allowMultiple
defaultValue
name
value

Spring not catch all object of my rest petition

My method is this:
#RequestMapping(value = "/asignar", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody
ResponseViewEntity<ResultadoJSON> asignar(
#RequestParam(required = true, value = "usuario") String usuario,
#RequestParam(required = true, value = "clienteId") Long clienteId,
ListaLotes lotes) {
....
}
Object ListaLotes
public class ListaLotes {
private List<LoteForm> lotes;
}
Object LoteForm
public class LoteForm {
private Long loteId;
private Long cantidad;
}
But when i realize the petition throught PostMan, the object "lotes" its always null
PETITION REST
Rest Header
Rest body
What I should do for it works ? I can't modify my Java code its part of an API. Only can modify de REST Petition
As has already been commented, if you want to transfer data to your controller, you need to use the POST method and mark the paramter as #RequestBody.
// or #PostMapping
#RequestMapping(value = "/asignar", method = RequestMethod.POST, headers = "Accept=application/json")
public #ResponseBody
ResponseViewEntity<ResultadoJSON> asignar(
#RequestParam(required = true, value = "usuario") String usuario,
#RequestParam(required = true, value = "clienteId") Long clienteId,
#RequestBody ListaLotes lotes) {
....
}

Spring - is it possible to give same url (path) in request mapping for two different post methods?

Is it possible to map same path (uri) in request mapping for two different post methods, only difference is request body.
Example
#RequestMapping(value = "/hello", method = RequestMethod.POST)
public String helloEmployee(#RequestBody Employee employee) {
return "Hello Employee";
}
#RequestMapping(value = "/hello", method = RequestMethod.POST)
public String helloStudent(#RequestBody Student student) {
return "Hello Student";
}
No, you can't give same url in request mapping of post method having different request body type but same media type. Below won't work:
#PostMapping(path = "/hello", consumes = MediaType.APPLICATION_JSON_VALUE)
public String hello(#RequestBody Pojo1 val) {
return "Hello";
}
#PostMapping(path = "/hello", consumes = MediaType.APPLICATION_JSON_VALUE)
public String hello(#RequestBody Pojo2 val) {
return "Hello";
}
If you have different media type, then it will. Below will work:
#PostMapping(path = "/hello", consumes = MediaType.APPLICATION_JSON_VALUE)
public String hello(#RequestBody Pojo val) {
return "Hello";
}
#PostMapping(path = "/hello", consumes = MediaType.TEXT_PLAIN_VALUE)
public String hello(#RequestBody String val) {
return "Hello";
}
Your RequestMapping should differ on at least one of the conditions; path,method,params,headers,consumes,produces
I needed the same url post mapping but it was giving me an error so I added different params and it worked for me
//url1 post mapping
#PostMapping(value = "/applicant/{step}", params = "validatedata")
//url2 post mapping
#PostMapping(value = "/applicant/{step}", params = "data")
if any of the below is different(as mentioned by the above answers)then you can have the same URL post mapping
path,method,params,headers,consumes,produces
In my case params was diffrent
Yes you can do that but you need to specify unique parameters signature in RequestMapping annotation:
public class MyController {
#RequestMapping(method = RequestMethod.POST, params = {"!name", "!name2"})
public String action(HttpServletRequest request, HttpServletResponse response){
// body
}
#RequestMapping(method = RequestMethod.POST, params = "name")
public String action(HttpServletRequest request, HttpServletResponse response,
#RequestParam(value = "name", required = true) String name) {
// body
}
}
`

Spring Request mapping with different parameters and one same parameter

I have spring code where there is request as follows :
#RequestMapping(method = RequestMethod.GET, value = {
EnterpriseLiterals.ROOT_URL_SIMPLE + "storeDepartments/search.json",
EnterpriseLiterals.ROOT_URL_SIMPLE + "storeDepartments/search" },params = { "!dealerStoreId" })
public Map<String, List<? extends AbstractDepartment>> getDepartments(
#RequestParam(value = "enterpriseId", required = true) String enterpriseId,#RequestParam(value = "responseFields", required = false) String responseFields)
And another request as :
#RequestMapping(method = RequestMethod.GET, value = {
EnterpriseLiterals.ROOT_URL_SIMPLE + "storeDepartments/search",
EnterpriseLiterals.ROOT_URL_SIMPLE + "storeDepartments/search.json" },params = {"!enterpriseId"})
#ResponseBody
public Map<String, List<AbstractDepartment>> getDepartmentListBasedOnStoreAndDeptType(#RequestParam(value = "dealerStoreId", required = true) String dealerStoreId,#RequestParam(value = "responseFields", required = false, defaultValue = "summary") String responseFields)
However, since there is responseFields in both the requests I am getting error when I call the above API's with responseFields saying "ResponseFields does not exist.".
Please help with solutions to solve this problem.

Spring Boot passing JSON and simple attributes to the same mapping

I'm new in Spring Boot and I want to have the same Request Mapping method for JSON and simple request params, for example:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestParam(value = "url",
required = false,
defaultValue = "https://goo.gl") String url,
#RequestParam(value = "word",
required = false,
defaultValue = "Search") String word,
#RequestBody String hereGoesJSON) {
//Do some stuff
}
So, when request goes with params, only #RequestParam will work, in other cases we will use #RequestBody annotation.
localhost:8080/start?url=htts://google.com&word=Luck
Or may bee I'll be able to write method like this, for accepting any params:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestBody String anyParam) {
//Parse this anyParam
}
?
I've not found this trick in spring documentation, so I will appreciate any links to it.
Okay, I've solved the problem :D
All that I just needed was 2 methods with the same mapping and explicitly specify RequestMethod type:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestParam(value = "url",
required = false,
defaultValue = "https://goo.gl") String url,
#RequestParam(value = "word",
required = false,
defaultValue = "Search") String word) throws InterruptedException {
//Do some stuff
}
#RequestMapping(value = "/start", method = RequestMethod.POST, consumes = "application/json")
public String startJsonProcess(#RequestBody String body) {
//Do another stuff with RequestBody
}
UPD: added "consumes = "application/json". It helps dividing simple POST requests and JSON POST requests.

Categories

Resources