Spring Framework 3 и атрибуты сеанса - PullRequest
22 голосов
/ 03 мая 2010

У меня есть объект формы, который я установил для запроса в обработчике запросов GET в моем контроллере Spring. При первом входе пользователя на страницу должен быть создан новый объект формы и установлен запрос. Если пользователь отправляет форму, то объект формы заполняется из запроса, и теперь объект формы имеет все атрибуты пользователя givern. Затем форма проверяется, и если проверка в порядке, то форма сохраняется в базе данных. Если форма не проверена, я хочу сохранить объект формы в сеансе, а затем перенаправить на страницу обработки запроса GET. Когда запрос перенаправляется в обработчик GET, он должен проверить, содержит ли сессия объект формы.

Я выяснил, что в Spring есть аннотация @SessionAttributes ("form"), но по какой-то причине следующее не работает, потому что в первый раз форма атрибута сеанса пуста и выдает ошибку:

org.springframework.web.HttpSessionRequiredException: Session attribute 'form' required - not found in session

Вот мой контроллер:

@RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm(@ModelAttribute("form") Form form) {
    ModelAndView mav = new ModelAndView("form");      
    if(form == null) form = new Form();
    mav.addObject("form", form);
    return mav;
}

@RequestMapping(value="form", method=RequestMethod.POST)
@Transactional(readOnly = true)
public ModelAndView saveForm(@ModelAttribute("form") Form form) {
    FormUtils.populate(form, request);
    if(form.validate())
    {
        formDao.save();         
    }
    else 
    {
        return viewForm(form);
    }
    return null;
}

Ответы [ 5 ]

32 голосов
/ 18 марта 2011

Выдает исключение, если контроллер вызывается впервые, даже если к классу добавлен @SessionAttributes ({"form"}). Поэтому добавьте следующий метод populateForm, чтобы исправить это.

@SessionAttributes({"form"})
@Controller
public class MyController {

   @ModelAttribute("form")
   public Form populateForm() {
       return new Form(); // populates form for the first time if its null
   }

   @RequestMapping(value="form", method=RequestMethod.GET)
   public ModelAndView viewForm(@ModelAttribute("form") Form form) {
       ModelAndView mav = new ModelAndView("form");      
       if(form == null) form = new Form();
       mav.addObject("form", form);
       return mav;
   }

   @RequestMapping(value="form", method=RequestMethod.POST)
   @Transactional(readOnly = true)
   public ModelAndView saveForm(@ModelAttribute("form") Form form) {
      // ..etc etc
   }
}
25 голосов
/ 03 мая 2010

Задача @SessionAttribute - привязать существующий объект модели к сеансу. Если он еще не существует, вам нужно определить его. На мой взгляд, это излишне сбивает с толку, но попробуйте что-то вроде этого:

@SessionAttributes({"form"})
@Controller
public class MyController {

   @RequestMapping(value="form", method=RequestMethod.GET)
   public ModelAndView viewForm(@ModelAttribute("form") Form form) {
       ModelAndView mav = new ModelAndView("form");      
       if(form == null) form = new Form();
       mav.addObject("form", form);
       return mav;
   }

   @RequestMapping(value="form", method=RequestMethod.POST)
   @Transactional(readOnly = true)
   public ModelAndView saveForm(@ModelAttribute("form") Form form) {
      // ..etc etc
   }
}

Обратите внимание, что @SessionAttributes объявлено в классе, а не в методе. На самом деле вы можете ставить все, что захотите, но я думаю, что в классе больше смысла.

Документация по этому может быть намного яснее, на мой взгляд.

1 голос
/ 20 апреля 2013
@Controller
@SessionAttributes("goal")
public class GoalController {

    @RequestMapping(value = "/addGoal", method = RequestMethod.GET)
    public String addGoal(Model model) {
        model.addAttribute("goal", new Goal(11));
        return "addGoal";
    }

    @RequestMapping(value = "/addGoal", method = RequestMethod.POST)
    public String addGoalMinutes(@ModelAttribute("goal") Goal goal) {
        System.out.println("goal minutes " + goal.getMinutes());
        return "addMinutes";
    }
}

На странице addGoal.jsp пользователь вводит любую сумму и отправляет страницу. Отправленное количество сохраняется в HTTP-сессии из-за

@ModelAttribute("goal") Goal goal

и

@ SessionAttributes ( "цель")

Без суммы @ModelAttribute ("goal"), введенной пользователем на странице addGoal, будет потеряно

1 голос
/ 31 июля 2011

если нет определенного объекта сеанса, поэтому я думаю, что это будет так:

@SessionAttributes({"form"})
    @Controller
    public class MyController {
   @RequestMapping(value="form", method=RequestMethod.GET)
   public ModelAndView viewForm() {
       ModelAndView mav = new ModelAndView("form");      
       if(form == null) form = new Form();
       mav.addObject("form", form);
       return mav;
   }

   @RequestMapping(value="form", method=RequestMethod.POST)
   @Transactional(readOnly = true)
   public ModelAndView saveForm(@ModelAttribute("form") Form form) {
      // ..etc etc
   }
}
0 голосов
/ 11 мая 2012

Я тоже с этим борюсь. Я прочитал этот пост, и он прояснил некоторые вещи:

Установить сессионную переменную пружины mvc 3

Насколько я понял, это в основном говорит:

  • что Spring помещает объекты, указанные в @SessionAttributes, в сеанс только на время между первым GET-запросом и POST-запросом, который следует за ним. После этого объект удаляется из сеанса. Я попробовал это в небольшом приложении, и оно одобрило утверждение.

Так что, если вы хотите, чтобы объекты сохранялись дольше в течение нескольких запросов GET и POST, вам придется добавить их вручную в HttpSession, как обычно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...