【问题标题】:Model population in Spring MVC @ExceptionHandlerSpring MVC @ExceptionHandler 中的模型填充
【发布时间】:2014-11-15 18:31:09
【问题描述】:

有没有办法让我的@ExceptionHandler 方法可以访问由触发相关异常的@RequestMapping 方法填充的模型属性?

或者,更具体地说,对于我的问题:传递给我的视图的模型有一些从 @ModelAttribute 填充的数据(例如有关用户帐户的详细信息)方法,我希望这些也设置在我的 @ 987654324@ 方法。

例如,由于我的错误视图页面使用与其他页面相同的标题和菜单,我想显示当前用户名(以及其他信息,例如未读消息的数量等)。

我知道@ExceptionHandler 存在于@Transaction 之外(应该如此!),所以我显然不能(也不想)再次运行一些查询。相反,我想预先填充 ModelMapModelAndView 或其他任何内容,并确保异常处理程序掌握了它 - 或者至少在渲染视图时模型数据可用。

我希望这个问题有意义,我对 Spring MVC 还很陌生,所以我可能会在这里和那里混合一些概念......

【问题讨论】:

    标签: java spring spring-mvc exception-handling


    【解决方案1】:

    ExceptionHandlerjavadoc 声明以下关于可以传递给处理程序方法的参数:

    允许使用此注解注解的处理程序方法 拥有非常灵活的签名。他们可能有以下论点 以下类型,按任意顺序:

    1. An exception argument: declared as a general Exception or as a more specific exception. This also serves as a mapping hint if the annotation itself does not narrow the exception types through its value().
    2. Request and/or response objects (Servlet API or Portlet API). You may choose any specific request/response type, e.g. ServletRequest / HttpServletRequest or PortletRequest / ActionRequest / RenderRequest. Note that in the Portlet case, an explicitly declared action/render argument is also used for mapping specific request types onto a handler method (in case of no other information given that differentiates between action and render requests).
    3. Session object (Servlet API or Portlet API): either HttpSession or PortletSession. An argument of this type will enforce the presence of a corresponding session. As a consequence, such an argument will never be null. Note that session access may not be thread-safe, in particular in a Servlet environment: Consider switching the "synchronizeOnSession" flag to "true" if multiple requests are allowed to access a session concurrently.
    4. WebRequest or NativeWebRequest. Allows for generic request parameter access as well as request/session attribute access, without ties to the native Servlet/Portlet API.
    5. Locale for the current request locale (determined by the most specific locale resolver available, i.e. the configured LocaleResolver in a Servlet environment and the portal locale in a Portlet environment).
    6. InputStream / Reader for access to the request's content. This will be the raw InputStream/Reader as exposed by the Servlet/Portlet API.
    7. OutputStream / Writer for generating the response's content. This will be the raw OutputStream/Writer as exposed by the Servlet/Portlet API. 
    8. Model as an alternative to returning a model map from the handler method. Note that the provided model is not pre-populated with regular model attributes and therefore always empty, as a convenience for preparing the model for an exception-specific view.
    

    因此,为了填充您将用于显示错误的视图模型,您可能必须使用WebRequest

    【讨论】:

    • 如果其他人发现它像我一样有帮助 - 在撰写本文时,上面链接的 Javadocs 包括第 8 个选项:“模型作为从处理程序方法返回模型映射的替代方案. 请注意,提供的模型未预先填充常规模型属性,因此始终为空,以便为特定于异常的视图准备模型“。这显然与freakman的答案中链接的博客文章相冲突,据我从实验中可以看出,这是正确的,而Javadocs是错误的。谢谢春天:)
    • @DaveyDaveDave 感谢您的评论。我添加了第 8 个选项。
    • 抱歉 - 我的意思是补充,经过更多调查后,我发现第 8 个选项仅在 v4.1.7 和 v4.2.2 之间的某个时间添加。需要明确的是,这里的模型参数与如果控制器方法没有例外地继续执行时的模型不同;这是一个新的空模型,可以在错误页面中填充和使用。
    【解决方案2】:

    认为这是可能的,但是:

    http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

    重要提示:模型不能是任何参数 @ExceptionHandler 方法。相反,在方法中设置模型 使用上面的 handleError() 所示的 ModelAndView。

    似乎您不能像在任何其他控制器中一样传递 ModelAndView,因此必须再次构建它 + 从 HttpServletRequest 获取可能的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 2011-07-19
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多