当前位置: 动力学知识库 > 问答 > 编程问答 >

Spring Framework 3 and session attributes

问题描述:

I have form object that I set to request in GET request handler in my Spring controller. First time user enters to page, a new form object should be made and set to request. If user sends form, then form object is populated from request and now form object has all user givern attributes. Then form is validated and if validation is ok, then form is saved to database. If form is not validated, I want to save form object to session and then redirect to GET request handling page. When request is redirected to GET handler, then it should check if session contains form object.

I have figured out that there is @SessionAttributes("form") annotation in Spring, but for some reason following doesnt work, because at first time, session attribute form is null and it gives error:

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

Here is my controller:

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

}

网友答案:

The job of @SessionAttribute is to bind an existing model object to the session. If it doesn't yet exist, you need to define it. It's unnecessarily confusing, in my opinion, but try something like this:

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

Note that the @SessionAttributes is declared on the class, rather than the method. You can put wherever you like, really, but I think it makes more sense on the class.

The documentation on this could be much clearer, in my opinion.

网友答案:

It throws Exception if controller called first time even though added @SessionAttributes({"form"}) to class. So add following populateForm method will fix this.

@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
   }
}
网友答案:

if there is no defined session object so I think it's gonna be like this:

@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
   }
}
网友答案:
@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";
    }
}

On page addGoal.jsp user enters any amount and submits page. Posted amount is stored in HTTP Session because of

@ModelAttribute("goal") Goal goal

and

@SessionAttributes("goal")

Without @ModelAttribute("goal") amount entered by user on addGoal page would be lost

网友答案:

I'm struggling with this as well. I read this post and it made some things clearer:

Set session variable spring mvc 3

As far as I understood it this basically says:

  • that Spring puts the objects specified by @SessionAttributes into the session only for the duration between the first GET request and the POST request that comes after it. After that the object is removed from the session. I tried it in a small application and it approved the statement.

So if you want to have objects that last longer throughout multiple GET and POST requests you will have to add them manually to the HttpSession, as usual.

分享给朋友:
您可能感兴趣的文章:
随机阅读: