how to use #Requestparam #RequestBody together in spring restful - spring

how to use #Requestparam #RequestBody together in spring restful
#RequestMapping(method = RequestMethod.POST, value = "/upate")
#ResponseBody
public ModelAndView availableCheck(
#RequestParam("key") String key, #RequestBody User user)
throws Exception {
//handle
//
}
I want to update user by unique key,so I need request key paramer and the new user json object.
Advance thanks!

There is some possible mistake: if you return a ModelAndView then it is highly unlikely that you want to be it the ResponseBody, therefore remove #ResponseBody.
The other problem is that RespondeBody is for strings. It mean put the Body string in this variable.
So it your user is the command object populated by some form, then just remove the #RequestBody annotation
#RequestMapping(method = RequestMethod.POST, value = "/upate")
public ModelAndView availableCheck(
#RequestParam("key") String key, User user)
throws Exception {
//handle
//
}

Related

Error 400 when receiving data from URL parameters en Spring MVC

I am trying to receive data from an URL with two parameters like this one:
http://localhost:80000/xxx/xxx/tickets/search?codprovincia=28&municipio=110000
No matter the approach, I am always getting a 400 error, but if I access the URL without the two parameters, the controller returns the view correctly (without the parameters, naturally)
This is the code of my controller:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping("tickets")
public String tickets(Model model, #RequestParam ("codprovincia") String codprovincia, #RequestParam ("municipio") String municipio, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
Extra info: if I use this URL:
http://localhost:9081/xxx/xxx/tickets/search/28/790000
And this code:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping(value = "buscar/{codprovincia}/{municipio}", method = RequestMethod.GET)
public String buscar(#PathVariable Integer codprovincia, #PathVariable Integer municipio ,Model model, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
It gets the parameters correctly. The problem is that I have to use the first URL. I have reviewed similar questions about similar issues, and I have implemented the solutions to those issues, but I get the 400 error regardless what I try (add value="xxx=, required=false, and other suggestions.)
For RequestParam, you need to explicitly add 'name' attribute
#RequestParam(name = "codprovincia"), #RequestParam (name = "municipio")
No need to for HttpServletRequest, unless you have reason
Also, in your 'tickets' method, RequestMapping is not conforming to your URL path.
I think it should be
#RequestMapping("/xxx/tickets/search")
Cheers!

optional parameter in Spring MVC method

I am learning spring MVC and come across these methos in spring contrller MVC 3.1
ControllerClass(){
#RequestMapping(....)
public String show( Model uiModel) {
return ".....";
}
#RequestMapping(value = "/{id}", params = "form", method = RequestMethod.POST)
public String update(#Valid Contact contact, BindingResult bindingResult, Model uiModel,
HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes, Locale locale,
#RequestParam(value="file", required=false) Part file) {
if (bindingResult.hasErrors()) {
...........
return ".....";
}
parameters like BindingResult , Model ,
HttpServletRequest , RedirectAttributes , Locale ,
#RequestParam(value="file", required=false) Part are optional but I wonder where I can find these optional parameter and under which situation it can appear in method.
Parameter:
BindingResult - imagine you have an registration-form and you would pre validate the user input, then you can use the BindingResult.
Model - After the user is registered, he wants to edit his own profile he goes to a edit site, in this site you would show the data from the user. Here you can search for the user and add the user-object to the model and in the template you can read the values from the model-attribute.
HttpServletRequest provides request information.
#RequestParam(value="file", required=false) from Spring:
annotated parameters for access to specific Servlet request parameters. Parameter values are converted to the declared method argument type
Imagine you have a table of users and you would edit one of these, you select an entry and there you can send the userId as a requestparam.
There is a similar attribute, it's called #PathVariable the main difference, the #PathVariable is mandatory. The #RequestParam is optional respectively for this exist a "fallback/default value".
The #PathVariable is a part from the url:
#RequestMapping(value = "/{login}/edit", method = RequestMethod.GET)
public ModelAndView editUserByLogin(#PathVariable("login") final String login, final Principal principal) {}
The other two I have not used yet.

#Valid and Binding Result for Data from DB

I am using Spring validation(JSR 303) in one of the web apps.I have no issues when a user submits data and spring validation works pretty neat.But I have a scenario where I have to fetch data from a service and validate it and then bind them to my view.(something non-form validation).How can I use #Valid in this case or does it have to be done differently?
Here is a sample code,i started with
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ModelAndView getView(
#PathVariable("id") final String id, #User user,
HttpSession session) {
User user= getUser();
BindingResult result = new BeanPropertyBindingResult(user, "user");
validator.validate(user, result);
if(result.hasErrors()){
logger.log(Level.ERROR, "Errors");
}
ModelAndView view = new ModelAndView ("home");
view.addObject("user",user );
view.addAllObject(result.getModel());
return view;
As far as I understand you need to inject default org.springframework.validation.Validator into your controller (if #Valid works you should be able to do it)
#Autowired
Validator validator;
run validation manually as follows
User user = ...;
BindingResult result = BeanPropertyBindingResult(user, "user");
validator.validate(user, result);
and merge results into ModelMap (declare it as argument of your method) as follows
model.addAllAttributes(result.getModel());

Spring #PathVariable integration test

I'm trying ot write an integration test for one of my methods, that handles a form submission.
The problem is that i use #PathVariable int id in the #RequestMapping of my controller.
I get the following error message when my test method reaches the .handle() part.
nested exception is java.lang.IllegalStateException: Could not find #PathVariable [id] in #RequestMapping
So the controller cant reach the id. I'm using request.setRequestURI("/url-" + s.getId()); But appareantly its not helping with setting up #PathVariable.
Is there any way to set up the #PathVariable of my Mock object?
Update:
Yeah, im useing MockHttpServletRequest and annotationMethodHandlerAdapter.handle in my test class.
The Controller:
#RequestMapping(method = RequestMethod.POST, params = {"edit" })
public String onSubmit(#ModelAttribute("sceneryEditForm") SceneryEditForm s,
#PathVariable int id, Model model) {
// some code that useing id
}
The test method:
#Test
public void testEditButton() throws Exception {
MyObject s = new MyObject();
request.setMethod("POST");
request.setRequestURI("/edit-" + s.getId());
request.setParameter("edit", "set");
final ModelAndView mav = new AnnotationMethodHandlerAdapter()
.handle(request, response, controller);
assertViewName(mav, "redirect:/view-" + s.getId());
}
The error is correct: there is no path variable id
You need to add the path expression with an placeholder id
#RequestMapping(value = "/something/{id}",
method = RequestMethod.POST,
params = {"edit" })
public String onSubmit(#ModelAttribute("sceneryEditForm") SceneryEditForm s,
#PathVariable int id, Model model) {
// some code that useing id
}

Spring request mapping with Paypal

For the return URL, it seem you have to define the whole URL like so:
String returnURL = "http://localhost:8080/appName/shopping/confirmorder";
Now, I have a problem with the request mapping:
#RequestMapping(value = "/shopping/confirmorder?token={token}&PayerID={payerID}", method = RequestMethod.GET)
public String doGet(#PathVariable("token") String token, #PathVariable("payerID") String payerID,
HttpServletRequest request) {
// do stuff
}
The controller is never called for some reason?
The final returnURL returned from Paypal is like this:
http://localhost:8080/appName/shopping/confirmorder?token=EC-4...G&PayerID=A...W
Note the Ids have been edited.
If you have two path variables named token and payerID, then the method signature should be
public void doGet(#PathVariable("token") String token,
#PathVariable("payerID") String token,
HttpServletRequest request,
HttpServletResponse response)
How did you expect Spring to put those two strings inside a single option parameter of type int?
See http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-uri-templates
Moreover, PathVariable is used to bind portions of the request path to method arguments. In your case, you have request parameters. You should thus use #RequestParam:
#RequestMapping(value = "/shopping/confirmorder", method = RequestMethod.GET)
public void doGet(#RequestParam("token") String token,
#RequestParam("PayerID") String token,
HttpServletRequest request,
HttpServletResponse response)
See http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestparam

Resources