Как да превключите от много аргументи @RequestParam към @ModelAttribute в метод на Spring Controller

Нов съм в пролетта и успях да събера данни от формуляр в JSP изглед и да изпратя моя формуляр на контролер. От данните, получени от изгледа, създавам моделен обект, който също съдържа други моделни обекти:

@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);
}

Как мога да заменя целите редове @RequestParam с по-малко редове, използвайки @ModelAttribute? Трябва ли също така да добавя анотацията @ModelAttribute към класовете на модела (FormResults, Topic, Wave)?

Благодаря.


person Adrian Bob    schedule 30.08.2012    source източник


Отговори (2)


@ModelAttribute не е наистина необходим тук. Това, което обикновено правя (но може би не е добре за вашия случай), е обект, съдържащ всички тези данни:

@RequestMapping(value = "/updateEntry", method = RequestMethod.GET)
public RedirectView updateAction(ModelAndView model, Options options) throws ParseException {
    ...
}

public static class Options {
    private String selectedWaveName,
    private int id,
    ...
    // Getters and setters
}
person sinuhepop    schedule 30.08.2012
comment
здравейте, благодаря за публикацията, въпросът ми тук е: как мога да изпратя опциите за опции на обекта от страницата jsp? тъй като контролерът, който публикувах, обработва заявката /updateEntry от jsp изгледа, който обработва данните, изпратени от формуляр, така че не знам как може да работи това? - person Adrian Bob; 31.08.2012
comment
@adrianbob: нещо като /updateEntry?id=4&selectedWaveName=xxx би свършило работа. - person sinuhepop; 31.08.2012

Анотацията ModelAttribute в крайна сметка проработи, открих, че когато използвате тази анотация, променливите, които предавате от предния край, в моя случай от JSP страницата, трябва да имат точно същото име като атрибутите, декларирани във you're модел клас!

Например, ако имате клас модел като:

public class FormResults {

private int id;
private Topic topic;
private Wave wave;
private String evidence;
private String action;
private String manager;
 ... }

Също така ви трябват getter и setter методи за всички атрибути на класа и конструктор по подразбиране!

Променливите, които изпращате от JSP страницата към метода на контролера, който използва @ModelAttribute анотация, ще бъдат именувани по следния начин:

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

И това също работи в случай, когато имате сложен обект, който има друг обект като атрибут (като в моя случай: тема, вълна). Всичко, което трябва да направите, е да наименувате тези входове с префикса на името на класа: ex: topic, wave, последван от атрибутите на този клас, ex: topic.id, wave.id ...

И ето подписа на метода на моя контролер:

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

Spring автоматично създава обект FormResults. Това е! :)

person Adrian Bob    schedule 16.09.2012
comment
Само съвет за бъдещите читатели: можете също просто да създадете сетери със същото име като параметъра (напр. public void setAction(private String action) {}), което ще бъде извикано автоматично чрез Spring. По този начин не сте ограничени до имената на параметрите на заявката във вашия обект на заявка (т.е. FormResults). Например, можете да имате private String lastAction вместо това -- просто го задайте по подходящ начин в сетера. - person Priidu Neemre; 19.05.2016