Spring 5.2.2 MVC(3)

     接着Spring 5.2.2 MVC (2)基于DispatcherServlet 的内容继续讲。java


异常状况
web

     若是在请求映射期间发生异常或请求处理程序(如@Controller)引起异常,DispatcherServlet将委托给HandlerExceptionResolver bean   chain(链) 以解决异常并提供替代处理,这种典型的错误响应。typescript

下表列出了可用的HandlerExceptionResolver 实现:浏览器


   1)chain(链) 解析器
微信

    经过在Spring配置中声明多个HandlerExceptionResolver bean并根据须要设置它们的order 属性,能够造成异常解析器链。order 属性越大,异常解决程序的位置就越晚。app

HandlerExceptionResolver 指定它能够返回:ui

  • 指向错误视图的ModelAndView spa

  • 若是异常是在解析器中处理的,则为空的ModelAndView .net

  • 若是异常仍然未解决,则为空,以便后续的解析器尝试,若是异常仍然保留在最后,则容许冒泡上升到Servlet容器。3d

MVC配置会自动声明为默认Spring MVC异常、@ResponseStatus注解的异常以及@ExceptionHandler方法的支持声明内置的解析器。能够自定义或替换该列表。

2)容器错误页

    若是任何HandlerExceptionResolver仍然没法解决异常,那么该异常将被保留以传播,或者若是响应状态设置为错误状态(即4xx、5xx),则Servlet容器能够在HTML中呈现默认的错误页。要自定义容器的默认错误页,能够在web.xml中声明错误页映射。下面的示例演示了如何执行此操做:

<error-page> <location>/error</location></error-page>

在前面的示例中,当出现异常或响应具备错误状态时,Servlet容器在容器内对配置的URL进行错误分派(例如/error)。而后由DispatcherServlet进行处理,可能将其映射到@Controller,后者能够实现返回带有model 的错误视图名称或返回JSON响应,以下例所示:

@RestControllerpublic class ErrorController {
@RequestMapping(path = "/error") public Map<String, Object> handle(HttpServletRequest request) { Map<String, Object> map = new HashMap<String, Object>(); map.put("status", request.getAttribute("javax.servlet.error.status_code")); map.put("reason", request.getAttribute("javax.servlet.error.message")); return map; }}

Servlet  API没有提供在Java中建立错误页映射的方法。可是你能够同时使用WebApplicationInitializer和最少的web.xml


view解析

    Spring MVC定义了ViewResolver View 接口,这些接口容许你在浏览器中渲染模型,而没必要绑定到特定的视图技术。ViewResolver 提供视图名称和实际视图之间的映射。View 访问地址在移交给特定视图技术以前的数据准备。

下表提供了有关ViewResolver 层次结构的详细信息(ViewResolver 实现):

1)处理(Handling)

    能够经过声明多个解析器bean来连接视图解析器,若是须要,还能够经过设置order 属性来指定顺序。记住,order 属性值越大,视图解析器在链中的位置就越晚。

    ViewResolver 的规范指定它能够返回null以指明找不到视图。可是,对于JSP和InternalResourceViewResolver,判断JSP是否存在的惟一方法是经过RequestDispatcher执行分派。因此必须将InternalResourceViewResolver 配置为视图解析器的总顺序中的最后一个。

    配置视图解析和将ViewResolver bean添加到Spring配置同样简单。MVC配置为视图解析器和添加无逻辑视图控制器提供了一个专用的配置API,这对于没有控制器逻辑的HTML模板呈现很是有用。

2)重定向(Redirecting

   视图名称中的特殊redirect:前缀容许你执行重定向。UrlBasedViewResolver (及其子类)将此识别为须要重定向的指令。视图名称的其他部分是重定向URL。

     实际效果与控制器返回RedirectView相同,但如今控制器自己能够根据逻辑视图名称进行操做。逻辑视图名称(例如redirect:/myapp/some/resource)相对于当前的Servlet上下文重定向,而redirect:https://myhost.com/some/arbitrary/path等名称重定向到绝对URL。

     注意,若是用@ResponseStatus注解了控制器方法,则注解值优先于RedirectView设置的响应状态。

3)转发(Forwarding)

    你还能够由UrlBasedViewResolver 和子类解析的视图名称使用特殊的forward:前缀。这将建立一个InternalResourceView,它执行RequestDispatcher.forward()。所以这个前缀对于InternalResourceViewResolver InternalResourceView (对于JSP)是没有用的,可是若是你使用另外一种视图技术,但仍然但愿强制资源的转发由Servlet/JSP引擎处理,那么它可能会有帮助。请注意,你也能够连接多个视图解析器。

4)内容规范(Content Negotiation)

     ContentNegotiatingViewResolver不解析视图自己,而是将其委托给其余视图解析器,并选择与客户端请求的表示相似的视图。能够经过Accept 头或查询参数(例如"/path?format=pdf")。

    ContentNegotiatingViewResolver经过将请求媒体类型与每一个ViewResolver关联的View 所支持的媒体类型(也称为Content-Type)进行比较,选择适当的View 来处理请求。列表中具备兼容Content-Type的第一个View 表示返回给客户端。若是ViewResolver链没法提供兼容视图,则会查找经过DefaultViews 属性指定的Views 列表。后一个选项适用于能够呈现当前资源的适当表示的单例视图,而无论逻辑视图名称如何。Accept头能够包含通配符(例如text/*),在这种状况下,Content-Typetext/xml的视图是兼容的匹配项。


明天把基于DispatcherServlet 的剩余内容讲完。


敬请持续关注。


欢迎关注和转发Spring中文社区(加微信群,能够关注后加我微信):


本文分享自微信公众号 - Spring中文社区(gh_81d233bb13a4)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索