Session Spring框架3和会话属性
我在Spring控制器中的GET请求处理程序中将表单对象设置为请求。用户第一次进入页面时,应创建一个新的表单对象并将其设置为请求。若用户发送表单,那个么表单对象将从请求中填充,现在表单对象具有所有用户给定的属性。然后对表单进行验证,若验证正常,则表单保存到数据库中。若表单未经验证,我想将表单对象保存到会话,然后重定向到“获取请求处理”页面。当请求被重定向到GET处理程序时,它应该检查会话是否包含表单对象 我发现Spring中有@SessionAttributes(“form”)注释,但由于某些原因,下面的注释不起作用,因为第一次,会话属性form为null,并且它给出了错误:Session Spring框架3和会话属性,session,spring-mvc,Session,Spring Mvc,我在Spring控制器中的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;
}
@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({"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
}
}
请注意,@SessionAttributes
是在类上声明的,而不是在方法上声明的。你可以放在任何你喜欢的地方,真的,但我认为这在课堂上更有意义
在我看来,这可能更清楚。若控制器第一次调用,即使在类中添加了@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
}
}
如果没有定义的会话对象,那么我认为它将是这样的:
@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({"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
}
}
我也在努力解决这个问题。我读了这篇文章,它让一些事情更清楚了: 据我所知,这基本上是说:
- Spring将@SessionAttributes指定的对象仅在第一个GET请求和之后的POST请求之间的时间段内放入会话。之后,对象将从会话中移除。我在一个小应用程序中尝试了它,它批准了该声明
@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
及
@会期贡献(“目标”)
如果没有@modeldattribute(“goal”),用户在addGoal页面上输入的数量将丢失这对我很有帮助,但如果第一次调用时抛出异常。如果spring实现允许访问会话属性的方法参数注释(与访问请求参数的方式相同),这将非常有用<代码>公共无效剂量测量(@SessionAttribute(“cat”)cat cat){+1,这是迄今为止我见过的最好的解决方法,直到spring决定添加
@ModelAttribute(required=false)
。谢谢你的提示,这真的开始让人头疼了。populateForm方法是我解决这个问题的关键。希望spring文档更清晰一点:(