Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 3 MVC - how to turn a form into a query string?

I have a simple Spring form that gets bound to a form object on post. The http POST handler does some work, and then needs to redirect to a new URL, passing the form data as querystring parameters.

So, assuming I have a form backing object with properties "param1" and "param2", I want to build a string that looks something like this:

redirect:/app/new/page?param1=value;param2=value

Now, Spring will automatically bind values FROM a querystring or a form post into my form object, but I want to GENERATE a querystring with values taken from the form object.

Obviously it's trivial to do this manually but since I'm going to have lots of different form backing objects, is there some built-in facility in Spring to generate a query string from a form object, suitable for building into a URL?

Thanks.

like image 705
David Avatar asked Mar 23 '10 16:03

David


People also ask

What is the use of @param annotation?

In Spring MVC, the @RequestParam annotation is used to read the form data and bind it automatically to the parameter present in the provided method. So, it ignores the requirement of HttpServletRequest object to read the provided data.

How do you write a parameter query?

Query parameters are a defined set of parameters attached to the end of a url. They are extensions of the URL that are used to help define specific content or actions based on the data being passed. To append query params to the end of a URL, a '? ' Is added followed immediately by a query parameter.

What is RequestParam?

@RequestParam is a Spring annotation used to bind a web request parameter to a method parameter. It has the following optional elements: defaultValue - used as a fallback when the request parameter is not provided or has an empty value. name - name of the request parameter to bind to.

How do you create a query string in Java?

To create a string-based query, specify the attribute names of entity classes directly as strings, rather than the attributes of the metamodel class. For example, this query finds all Pet entities where the value of the name attribute is Fido: CriteriaQuery<Pet> cq = cb. createQuery(Pet.


2 Answers

OK, after some tracing into the Spring source code, I think I have some definitive answers.

1) Manually adding query parameters to a URL that you pass back in a "redirect:..." string is A VERY BAD IDEA. Spring caches the views those urls refer to, so if you specify lots of different parameters, you effectively leak memory by making the cache hold lots of values it doesn't need to.

Note that the PetClinic example code in the Spring distribution does exactly this, and apparently there has been a Jira issue raised to correct it :-)

2) The model object is still held by Spring when the controller returns, and Spring WILL automatically add any values in it onto the URL you specify (as query parameters) - PROVIDED that the model values are plain String or primitive objects. Now, since the form backing object is an Object stored as a single attribute, Spring doesn't do anything with it.

So - from an annotated Controller, the best approach seems to be to add a ModelMap parameter to the handler method. When you're ready to return, do something like this:

Assuming the form backing object "formObject" has been passed as a parameter to the controller handler method (via the ModelAttribute annotation) and has properties "param1" and "param2" that are Strings -

modelMap.clear();
modelMap.addAttribute("param1", formObject.getParam1());
modelMap.addAttribute("param2", formObject.getParam2());
return "redirect:/my/url";

And Spring will issue a redirect to /my/url?param1=value;param2=value

There doesn't appear to be a built-in mechanism (in Spring) to turn a bean into a list of key/value pairs for adding into the map, but if you really need that, the Apache BeanUtils library will do nicely. Of course, you don't want to do this for big objects otherwise you might exceed the allowable length of a URL.

Finding all that out seemed to be much harder than it needed to be :-)

like image 114
David Avatar answered Sep 30 '22 13:09

David


Map<String, Object> model = new HashMap<String, Object();
model.put("stuff", "here");
ModelAndView mv = new ModelAndView("redirect:/somewhere.htm", model);
return mv;

Produces

http://.../somewhere.htm?stuff=here
like image 26
dev101 Avatar answered Sep 30 '22 15:09

dev101