1.1 DispatcherServlet 调度程序

一、上下文层次结构

         mvc context hierarchy

二、特殊的bean类型

   目的:处理请求并且返回响应

   1.HandlerMapping                   映射处理器。一个请求映射到一个handler,进行预处理和后期处理。两个重要的实现RequestMappingHandlerMapping(支持@RequestMapping)和SimpleUrlHandlerMapping (为     处理程序维护URI路径模式的显式注册)

   2.HandlerAdapter                    适配处理器。帮助DispatcherServlet 调用处理器,使一个请求映射到一个handler;

   3.HandlerExceptionResovler   异常处理解析器。 处理异常,可以映射异常到handler,错误页面或者其他地方;

   4.ViewResolver                        视图解析器。把一个handler解析为视图,提交给Response。

   5.LocaleResolver                     时区解析器。

   6.ThemeResolver                    主题解析器。

   7.MultipartResolver                  文件上传解析器。

   8.FlashMapManager                FlashMap管理。存储和获取FlashMap,在重定向的时候,使属性共享。

三、Web MVC 配置

   应用程序可以声明基础的特殊Bean类型,这些类型用来处理请求。DispatcherServlet检查每个特殊bean的WebApplicationContext。如果没有匹配的bean类型,它将返回DispatcherServlet.properties中列出的默认类     型。

四、Servlet 配置

      基于xml配置,继承AbstractDispatcherServletInitializer,重写createServletApplicationContext方法,

@Override
    protected WebApplicationContext createServletApplicationContext() {
        XmlWebApplicationContext cxt = new XmlWebApplicationContext();
        cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
        return cxt;
    }

 

     AbstractDispatcherServletInitializer也能增加Filter实例,每个过滤器都根据其具体类型添加一个默认名称,并自动映射到DispatcherServlet。

     AbstractDispatcherServletInitializer的isAsyncSupported protected方法提供了一个位置来在DispatcherServlet并且映射所有过滤器到它上,启用异步支持。默认情况下,此标志设置为true。

四、处理请求

    DispatcherServlet处理请求方式如下:

    1.WebApplicationContext被绑定在请求中,并且能让controller和其他元素使用。默认被绑定在DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE。

    2.LocaleResolver 被绑定在请求中

    3.ThemeResolver 被绑定在请求中

    4.文件请求被包装在MultipartHttpServletRequest

    5.链式执行

    6.有model,返回view。没有model,不渲染view。

    7.支持返回last-modification-date。如果实现了LastModified,返回最后修改的时间。

    8.contextClass   实现ConfigurableWebApplicationContext的类,由这个Servlet实例化并在本地配置。默认情况下,使用XmlWebApplicationContext

    9.contextConfigLocation  传递给上下文实例(由contextClass指定)的字符串,以指示可以在何处找到上下文。字符串可能由多个字符串(使用逗号作为分隔符)组成,以支持多个上下文。对于定义了两次bean的多个上      下文位置,最新位置优先。

    10.namespace  WebApplicationContext的名称空间。默认为servlet-name servlet

    11.throwExceptionIfNoHandlerFound   当没有为请求找到处理程序时,是否抛出NoHandlerFoundException。然后可以使用HandlerExceptionResolver捕获异常(例如,通过使用@ExceptionHandler控制器方法),并      像处理其他异常一样处理异常。默认情况下,这被设置为false,在这种情况下DispatcherServlet将响应状态设置为404 (NOT_FOUND),而不会引发异常。注意,如果还配置了缺省servlet处理,未解决的请求总是转发到缺省servlet,并且从来不会引发404。

五、拦截请求

     要想实现拦截请求,就要实现HandlerInterceptor,它有三个方法:

     preHandle: 应用程序被执行前。

     postHandle:应用程序执行后,还没有渲染视图,可以对modelAndView进行操作。

     afterCompletion:完成完整的请求后,视图渲染完成后。

     perHandle方法会返回一个boolean类型,如果返回true,继续执行下一个拦截器;如果返回false,DispatcherServlet假设这个拦截器已经处理了请求(例如,呈现了一个完整的视图),并且不再执行下一个拦截器和应用程序。

     注意:postHandle是不能对 @ResponseBody和@ResponseEntity 注解起作用的,这些方法被编写和提交在 HandlerAdapter 之中并且在postHandle之前。所以如果你想在response中增加一个header,postHandle方法是不行的。针对这个情况,你可以实现ResponseBodyAdvice接口,并将其实现在Controller Advice bean 中,或者直接在RequestMappingHandlerAdapter中配置。

六、异常处理

      SimpleMappingExceptionResolver : 异常类名和错误页面之间的映射;

      DefaultHandlerExceptionResolver :  Spring MVC的异常和 Http状态码的映射;

      ResponseStatusExceptionResolver: @ResponseStatus的异常和 Http状态码的映射,Http状态码的值是注解上标记的值;

      ExceptionHandlerExceptionResolver:通过调用@Controller或@ControllerAdvice类中的@ExceptionHandler方法来解决异常;

      (1)异常链

      在Spring配置文件中,可以声明多个HandlerExceptionResolver类,并且执行顺序和配置顺序相同;

      异常链返回的规定是:

      1、返回一个ModelAndView指向错误的视图;

      2、如果异常已经在内部被解决,返回一个空的ModelAndView,;

      3、如果异常没有被解决,返回null,以便后面的解析器尝试解决;如果异常在最后仍然存在,就把异常扔到Servlet容器中;

      MVC Config 自动声明了内部解析器去处理Spring MVC 的异常。为了支持@ResponseStatus的异常和@ExceptionHandler的方法,可以自定义内部声明的列表或者替换它;

      (2)容器中的错误页面 

       如果任何异常解析器都无法处理异常,导致异常响应给浏览器或者响应的状态码为4xx、5xx。这时Servlet容器能渲染一个默认的html页面,你能在web.xml中配置这个页面的uri,如下代码;

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

         Servlet API不提供在Java中创建错误页面映射的方法。但是,您可以同时使用WebApplicationInitializer和web.xml。

七、视图处理

       ViewResolver 是父接口

       AbstractCachingViewResolver :AbstractCachingViewResolver的子类缓存已经解析的视图实例。缓存提高了某些视图技术的性能。您可以通过将cache属性设置为false来关闭缓存。此外,如果必须在运行时刷新某个视图(例如,修改FreeMarker模板时),可以使用removeFromCache(String viewName, Locale loc)方法。

     XmlViewResolver:支持XML的配置文件,默认/WEB-INF/views.xml;

     ResourceBundleViewResolver:使用bean在ResourceBundle中声明,支持解析每一个视图,使用  [viewname].(class)  作为视图类,使用 [viewname].url 作为视图URL。

     UrlBasedViewResolver:该接口在没有显式映射定义的情况下,能直接解析逻辑视图名称到url。如果逻辑名称以一种直接的方式匹配视图资源的名称,而不需要任意映射,那么这是合适的。

     InternalResourceViewResolver:UrlBasedViewResolver的便捷子类,它支持内部资源视图(实际上,servlet和jsp)、JstlView和TilesView子类。可以使用setViewClass(..)为这个解析器生成的所有视图指定视图类。

    FreeMarkerViewResolver:UrlBasedViewResolver的便捷子类,支持FreeMarkerView和它们的自定义子类;

    ContentNegotiatingViewResolver:它根据 请求文件名 或 Accept header 解析视图;

    (1)处理

      ViewResolver的契约指定它可以返回null来表示找不到视图。然而,对于JSP和InternalResourceViewResolver,判断JSP是否存在的惟一方法是通过RequestDispatcher执行分派。因此,必须始终配置一个InternalResourceViewResolver,使其在视图解析器的整体顺序中位于最后。

    (2)重定向redirect

      视图名字的前缀表明了重定向操作,UrlBasedViewResolver及其子类承认重定向被需要。redirect:/myapp/some/resource在当前Servlet的上下文中寻找,redirect:https://myhost.com/some/arbitrary/path重定向到一个完整的URL;

    (3)转发forward

      这将创建一个internalresourceview,它执行RequestDispatcher.forward()。对于InternalResourceViewResolver和InternalResourceView(对于JSP),这个前缀是没有用的,但是如果您使用另一种视图技术,但是仍然希望强制Servlet/JSP引擎处理资源的转发,那么这个前缀是有用的。

     (4)内容协商

      ContentNegotiatingViewResolver本身并不解析视图,而是委托给其他视图解析器,并选择与客户端请求的表示形式类似的视图。表示可以通过Accept头或查询参数(例如,“/path?format=pdf”)确定。  ContentNegotiatingViewResolver通过将请求媒体类型与每个视图解析器关联的视图支持的媒体类型(也称为内容类型)进行比较,选择适当的视图来处理请求。列表中具有兼容内容类型的第一个视图将表示返回给客户机。如果ViewResolver链不能提供兼容的视图,则会参考通过DefaultViews属性指定的视图列表。后一个选项适用于能够呈现当前的适当表示形式的单例视图。Accept头可以包含通配符(例如text/*),在这种情况下,内容类型为text/xml的视图是兼容的匹配。

八、语言环境

     时区TimeZoo :除了获取客户端的语言环境之外,了解其时区通常也很有用。该LocaleContextResolver接口提供了一个扩展LocaleResolver,让解析器提供了更丰富的LocaleContext,其中可能包括时区信息。TimeZone可以通过RequestContext.getTimeZone()方法获得 用户。时区信息被Spring注册的对象ConversionService自动转化成任何 Date/Time 的ConverterFormatter。

     header 解析器

     环境解析器拦截请求的 accept-language 字段。通常,header字段包含客户端操作系统的语言环境。注意,这个这个解析器不支持 TimeZoo 的信息

     Cookie 解析器

     环境解析器会拦截请求的 Cookie 字段,看看是否有 Locale 和 Time 被制指定。如果有,使用这些指定的信息。通过使用语言环境解析器的属性,你能指定cookie的名字和最大的年龄。下面是CookieLocaleResolver的例子:

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">

    <property name="cookieName" value="clientlanguage"/>

    <!-- in seconds. If set to -1, the cookie is not persisted (deleted when browser shuts down) -->
    <property name="cookieMaxAge" value="100000"/>

</bean>

     以下是CookieLocaleResolver的属性:

      Session 解析器

      SessionLocaleResolver允许您从可能与用户请求关联的会话中获得 Local 和 TimeZoo。与CookieLocaleResolver相反,该策略将本地选择的地区设置存储在Servlet容器的HttpSession中。因此,这些设置对于每个会话都是临时的,因此,当每个会话终止时,这些设置就会丢失。

      注意,它与外部会话管理机制(如Spring会话项目)没有直接关系。这个SessionLocaleResolver根据当前HttpServletRequest计算和修改相应的HttpSession属性。

      Locale  拦截器

      您可以通过将LocaleChangeInterceptor添加到HandlerMapping定义之一来启用更改地区。它检测请求中的一个参数并相应地更改区域设置,在dispatcher的应用程序上下文中调用LocaleResolver上的setLocale方法。下面的例子展示了,调用  *.view 的资源就会包含了一个参数siteLanguage。例如,一个URL请求https://www.sf.net/home.view?siteLanguage=nl,就会将站点语言更改为荷兰语。以下是配置

<bean id="localeChangeInterceptor"
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
    <property name="paramName" value="siteLanguage"/>
</bean>

<bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>

<bean id="urlMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="interceptors">
        <list>
            <ref bean="localeChangeInterceptor"/>
        </list>
    </property>
    <property name="mappings">
        <value>/**/*.view=someController</value>
    </property>
</bean>

九、多部分解析器

   org.springframework.web.multipart 包中的 MultipartResolver 能解析多部分请求包括文件的上传和下载;一个是基于Commons FileUpload实现的,另一个是基于Servlet 3.0 的多部分请求解析的;

   想要使用多部分处理,需要在 DispatcherServlet 的Spring 配置中声明一个 MultipartResolver 的bean 。当一个POST请求,它的 content-type = multipart/from-data ,解析器解析内容并且包裹这个当前的 HttpServletRequest 作为 MultipartHttpServletRequest ,把解析的内容作为request的参数。

  (1) Apache Commons FileUpload

   使用Commons FileUpload 需要配置一个类型为 CommonsMultipartResolver 的bean。需要进入 commons-fileupload 的依赖包。

  (2)Servlet 3.0

   使用Servlet 3.0 的多部分解析需要通过Servlet容器的设置。这样做:

   1.在java中,设置 MultipartConfigElement 在Servlet注册中。

   2.在 web.xml 中,增加<multipart-config> 部分在Servlet 的声明中。

十、日志

   DEBUG-level :Spring MVC中的调试级日志记录被设计为紧凑、最小且人性化。它着重于反复有用的高价值信息,而不是只在调试特定问题时有用的其他信息。

   TRACE-level :跟踪级日志通常遵循与调试相同的原则(例如,也不应该是消防软管),但是可以用于调试任何问题。此外,一些日志消息在跟踪和调试时可能显示不同级别的详细信息。

   调试和跟踪日志记录可能会记录敏感信息。这就是为什么请求参数和头在缺省情况下被屏蔽,并且必须通过DispatcherServlet上的enableLoggingRequestDetails属性显式地启用它们的完整登录

转载于:https://www.cnblogs.com/smailjunk/p/11177858.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值