Search code examples
javaspringjspcontrollerspring-annotations

How to switch from many @RequestParam arguments to @ModelAttribute in a Spring Controller method


I' new to spring and i've managed to collect data from a form in a JSP view and to submit my form to a controller . From the data aquired from the view , i'm instantiating a model object , which also contains other model objects :

@RequestMapping(value = "/updateEntry", method = RequestMethod.GET)
public RedirectView updateAction(ModelAndView model,
@RequestParam(value = "name", defaultValue = "none") String selectedWaveName,
@RequestParam(value = "id", defaultValue = "-1") int id,
@RequestParam(value = "function", defaultValue = "none") String function,
@RequestParam(value = "evidence", defaultValue = "none") String evidence,
@RequestParam(value = "action", defaultValue = "none") String action,
@RequestParam(value = "topicId", defaultValue = "-1") int topicId,
@RequestParam(value = "topic", defaultValue = "none") String topic,
@RequestParam(value = "topicDesc", defaultValue = "none") String topicDesc,
@RequestParam(value = "waveId", defaultValue = "-1") int waveId,
@RequestParam(value = "waveStart", defaultValue = "none") String waveStart,
@RequestParam(value = "waveEnd", defaultValue = "none") String waveEnd)
throws ParseException {

DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
Date dateStart = formatter.parse(waveStart);;
Date dateEnd = formatter.parse(waveEnd);

waveDAO.updateFormResults(new FormResults(id, 
new Topic(topicId, topic, topicDesc), 
new Wave(waveId, selectedWaveName, dateStart, dateEnd), 
evidence, action, function));
return new RedirectView("/hr/?name=" + selectedWaveName);
}

How can i replace the whole @RequestParam lines with fewer lines using @ModelAttribute ? Do i also need to add the @ModelAttribute annotation to the model classes (FormResults , Topic , Wave) ?

Thanks.


Solution

  • The ModelAttribute annotation did work eventually , I found out that when using this annotation , the variables that you're passing from the front end , in my case from the JSP page , should have the exactly same name as the attributes declared in you're model class !

    For example if you have a model class like :

    public class FormResults {
    
    private int id;
    private Topic topic;
    private Wave wave;
    private String evidence;
    private String action;
    private String manager;
     ... }
    

    Also you need getter and setter methods for all the class attributes , and a default constructor !

    The variables which you are sending from the JSP page , to the controller method that uses @ModelAttribute annotation , would be named like this :

    <input type="text" name="id"     ...
    <input type="text" name="evidence" ...
    <input type="text" name="action"   ....
    <input type="text" name="manager"  ...
    

    And this also works in the case where you have a complex object that has another object as attribute (like in my case : Topic , Wave). All you have to do is name those inputs with the prefix of the class name : ex: topic , wave , followed by that classes attributes , ex: topic.id , wave.id ...

    And here is my controller method's signature :

    @RequestMapping(value = "/updateEntry", method = RequestMethod.GET)
    public ModelAndView updateAction(ModelAndView model,
            @ModelAttribute("fr") FormResults fr) throws ParseException {
    ...}
    

    Spring automatically creates a FormResults object . That`s it! :)