【问题标题】:@SessionAttributes gives HttpSessionRequiredException@SessionAttributes 给出 HttpSessionRequiredException
【发布时间】:2011-09-04 02:55:01
【问题描述】:

我正在使用 Spring MVC 3.0.5。我正在尝试学习如何使用@SessionAttributes。这是我的代码示例:

@Controller
@SessionAttributes("book")
public class BookController {

    @RequestMapping("/book/bookForm.htm")
    public ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, @Valid @ModelAttribute("book") Book book, BindingResult result) throws Exception {

        ModelMap modelMap = new ModelMap();

        return new ModelAndView("bookForm", modelMap);
    }

}

当我尝试转到 /book/bookForm.htm 时出现异常:

org.springframework.web.HttpSessionRequiredException: Session attribute 'book' required - not found in session
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.raiseSessionRequiredException(AnnotationMethodHandlerAdapter.java:722)
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveModelAttribute(HandlerMethodInvoker.java:758)
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:356)
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

我该如何解决这个问题?

我也尝试过这个答案:

Spring Framework 3 and session attributes

关于该答案的一些问题:

  1. 提问者的代码和选择的答案的代码看起来基本相同……那么解决问题的补充在哪里?

  2. 试图阅读documentation,我无法理解这个注释实际上做了什么:

相关命令对象何时保存在会话中?是在我们进入控制器的方法时,还是在离开时,还是每次操作命令对象的内容时......?命令对象何时开始保存在会话中?

谢谢!

【问题讨论】:

  • 你找到答案了吗?我也面临同样的问题

标签: java spring spring-mvc annotations


【解决方案1】:

基本上,使用 Spring 注释选择的“默认方法”是第一次调用页面时参数最少的方法。方法越具体,它就越不可能成为默认方法。

如果你把你的 @RequestMapping("/book/bookForm.htm") 放在这样的方法上:

@RequestMapping("/book/bookForm.htm")
public ModelAndView setupForm() throws Exception {

    ModelMap modelMap = new ModelMap();
    // I don't remember the exact syntax here - pretending its a java.util.Map.
    modelMap.put("book", new Book());

    return new ModelAndView("bookForm", modelMap);
}

这将是默认设置,因为它的参数数量最少。您必须在第一次请求页面时创建表单并将其放入会话/模型和视图/模型地图/厨房接收器(说真的,RequestMapping 参数组合既棒又可笑)。之后,将根据您现在实际存储“book”会话属性(因为它被放置在“book”键下)这一事实,适当地调用各个方法。

参数名称和值等都决定了在默认之后调用哪个方法 - 这是配置控制器以响应 Web 请求的一种非常好的和灵活的方式,但它确实需要一些时间来适应。

【讨论】:

  • (1) 我不认为你所说的 Spring 选择默认方法是基于它们有多少参数是正确的。如果这是真的,那么为什么我不只是拥有您编写的 setupForm() 方法,没有 @RequestMapping - 它有参数,所以 Spring 总是会选择它? AFAIK Spring 通过他们的@RequestMapping 选择方法......(2)“您必须创建表单并将其放入会话/模型中......在页面的第一个请求中。”你的意思是我必须让用户点击一些虚拟链接<a href="setupForm.htm">kindly start up this app</a> 才能开始工作?
  • (3) 我仍然希望能解释一下我的代码失败的原因、Spring 的预期、@SessionAttributes 的作用和时间。或者对所有解释的地方的一些参考。因为它不在 javadoc 上。
  • 我的第一条评论应该是:“没有@RequestMapping - 它没有参数”——这个系统不允许我编辑我的cmets。
  • 您必须使用 @RequestMapping 注释您的方法才能将其作为控制器方法处理。 Spring 尝试精确匹配方法签名,因此在缺少数据的情况下,它将使用信息量最少的那个。如果您有更多数据(在您的情况下,您实际上将在第一种方法之后获得表格),它将匹配那些更具体的方法。至于(2),无论您使用什么控制器策略,总是如此 - 链接的第一次点击需要设置表单(现在,这并不是说它不能(继续(2))。
  • (2) 一个链接,例如 /book/bookForm.htm?bookId=345。在这种情况下,您可以使用如下参数映射:@RequestMapping(value = "/book/bookForm.htm", params="bookId") public ModelAndView setupForm(@RequestParam(value="bookId", required = true) final int bookId) { Book book = bookService.getBook(bookId);模型映射模型映射 = 新模型映射(); // 我不记得这里的确切语法 - 假装它是 java.util.Map。 modelMap.put("书", 书); return new ModelAndView("bookForm", modelMap); }
【解决方案2】:

在控制器类中添加这些代码行

@ModelAttribute("book")
    public UserObject getBookObject() {
        return new Book();

    }

在使用 SessuinAttributes 时,你需要使用上述代码在会话中添加对象

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    相关资源
    最近更新 更多