b spring mvc详解--官方文档翻译

–> go to 总目录

文章目录

    • 1.1 DispatcherServlet
      • 1.1.1 Context的结构层次
      • 1.1.2 Special Bean Types 特殊的Bean类型。
      • 1.1.3 Web MVC Config
      • 1.1.4 Servlet Config
      • 1.1.5 Processing 处理逻辑
      • 1.1.6. Interception 介入
      • 1.1.7 异常
        • Chain of Resolvers resolver链
        • Container Error Page
      • 1.1.8 view Resolution
        • Handling
        • Redirecting
        • Forwarding
        • Content Negotiation
      • 1.1.9 Locale
        • Time Zone
        • Header Resolver
        • Cookie Resolver
        • Session Resolver
        • Locale Interceptor
        • Session Resolver
        • Locale Interceptor
      • 1.1.10 Themes
        • Defining a theme
        • Resolving Themes
      • 1.1.11. Multipart Resolver
        • Apache Commons FileUpload
        • Servlet 3.0
      • 1.1.12. Logging
        • 敏感数据

大名鼎鼎的Spring MVC。
Spring MVC是基于原生的 Servlet API和Spring。
从Spring-5.0开始并行化一个新的Web框架spring-webflux。都会在后面介绍。

1.1 DispatcherServlet

分发器。像大多数web框架一样,围绕着前置controller模式,指一个中心的 Servlet(DispatcherServlet),提供对请求处理的分享算法,真实的工作交给配置的组件。这种模式是灵活和支持分流。
核心的DispatcherServlet需要使用java配置或者web.xml来配置。反过来DispatcherServlet使用Spring的配置来发现他委托的组件:mapping,view resolution,exception handling处理等。
使用java配置注册和初始化DispatcherServlet

分发器

1.1.1 Context的结构层次

DispatchServlet希望WebApplicationContext(从Application扩展)有自己的配置。WebApplicationContext有对ServletContextServlet的链接。同时也会被绑定到ServletContext,以便于RequestContextUtils静态方法反向找到WebApplicationContext。
对于很多应用来说一个独立的WebApplicationContext就够了。但是也有可能有一个层次化的context结构,一个root WebApplicationContext被多个DispatcherServlet(或者其他Servlet)共享,每一个都拥有子WebApplicationContext配置。
root WebApplicationContext典型的包含基础设施bean,例如
data repositories 和 business services,需要被多个servlet共享。这些bean可以被有效的复用和重用,典型的每个Servlet拥有本地版的bean。
层次图


等效的xml配置

1.1.2 Special Bean Types 特殊的Bean类型。

DispatcherServlet委托给特殊的bean去处理request和提供合适的response。这里的特殊bean指的是被Spring-managed管理的的实例,也实现Spring框架,这些类通常是自带的,但是你也可以去自定义。

bean type 解释
HandlerMapping 映射一个request到一个handler,且拥有一堆链式的拦截器pre-和post-。映射是基于一些准则,但是各自的实现有很大差异。两个主要的HandlerMapping实现是RequestMappingHandlerMapping支持@requestMapping)和SimpleUrlHandlerMapping(对URI path有明确的要求)
HandlerAdapter 帮助DispatchServlet去调用Handler(当请求来的时候),无视真实的handler是如何调用的。这个类的主要目的是帮助DispatcherServlet无需关注调用handler的实现细节
HandlerExceptionResolver 解决异常的策略,有可能将异常路由到handler,到HTML的错误*(如404,500页面)
ViewResolver 解决将String-based viewname对应到真实的view页面作为响应
LocaleEsolver,localContextResolver 解决本地化的client端提供一个时间域,然后提供国家化的视图
ThemeResolver 解决你web应用的主题
MultipartResolver 解析分片请求multi-part request(比如brower 格式化 文件上传)
FlashMapManager 存储和解析"input"和"output",flashMap可以将一个请求的属性传递给另外一个

1.1.3 Web MVC Config

应用可以声明基础设施bean如上面1.1.2所列的来处理请求。DispatcherServlet会为每个special bean来检查WebApplicationContext。如果没有匹配的bean类型,他会使用DispatcherServlet.properties配置默认标识的类型。
大多数场景,mvc config是最佳的开始。他用java或者xml提供一个high-level的配置。

1.1.4 Servlet Config

Servlet 3.0+,你可以用是用代码或者web.xml来配置Servlet 容器。下列示例注册一个DispatcherServlet
b spring mvc详解--官方文档翻译_第1张图片
WebApplicationInitializer是Spring MVC提供的一个接口,确保你的实现能被检测到,并自动应用到Servlet 3容器。一个WebApplicationInitializer的抽象实现是AbstractDispatcherServletInitializer让你更容易的注册DispatcherServlet通过覆盖指定的方法。
use Java-based的配置推荐如下模板
b spring mvc详解--官方文档翻译_第2张图片
如果你是用XML-based的Spring 配置,你应该是用AbstractDispatcherServletInitializer,如下
b spring mvc详解--官方文档翻译_第3张图片
AbstractDispatcherServletInitializer也提供添加Filter实例,自动会添加到DispatcherServlet
b spring mvc详解--官方文档翻译_第4张图片

1.1.5 Processing 处理逻辑

DispatchServlet处理请求的流程如下

  • WebApplicationContext被搜索并作为一个属性绑定到request中去,会被controller和其他process中元素使用到。默认会被绑定到 DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTEkey下
  • 本地的Resolver被绑定到request上,去解决本地处理请求需要使用的资源(渲染 view,准备数据等等)。如果不需要本地Resolver,那么你就不需要这一层,。
  • theme resolver ,主题resolver会被绑定到request上去让成员,比如views去侦测到具体哪个主体可以被使用,如果你不需要这个主题层,那么你可以忽视他。
  • 如果你具体指定了一个multipart file resolver,request会被multiparts侦测到。如果multiparts被发现了,request会被包裹在MultipartHttpServletRequest中,为proccess的其他元素提供进一步的处理。
  • 寻找合适的handler。如果hanler被找到了,关联在这个hanlder上的(preprocessors, postprocessors, and controllers) 执行链,被按顺序执行,目的去准备一个model和渲染。换句话说,有注解的controller,他的response会被(在HandlerAdapter)中的渲染,而不是返回一个view。
  • 如果一个model被返回了,这个view也被渲染了。如果没有mode被返回(maybe due to a preprocessor or postprocessor intercepting the request, perhaps for security reasons),没有view被提供,那就是因为request早已经被实现了。

被声明在WebApplicationContext中的HandlerExceptionResolverbean,被用来解决处理request proceesing的异常。这个resolver可以被自定义
Spring的DispatcherServlet支持返回last-modification-date(最后修改日期),由于Sevelet 的具体API。对于一个具体 的request,process支持侦测最后一次的修改日期:这DispatcherServlet寻找合适嗯handler(实现LastModified)。如果找到了LastModifiedgetLastModified(request)方法被返回给client。
你可以自定义分离的DispatcherServlet实例,通过添加到Servelt初始化参数(init-param elements)到web.xml中去。下列的表列举了被支持的参数
b spring mvc详解--官方文档翻译_第5张图片

1.1.6. Interception 介入

HandlerMapping的实现支持handler interceptors是十分有用的,当你想为request应用一些特殊的规则-例如检查。Interception必须实现org.springframework.web.servlet中的HandlerInterceptor,其包含了三个灵活的方法:

  • preHandle(…): Before the actual handler is executed。return boolean
  • postHandle(…): After the handler is executed
  • afterCompletion(…): After the complete request has finished

preHandle(…)返回一个boolean用来确定,是否继续执行下来的调用链。true执行,false中断。
postHandle(…)很少被用到。是用@ResponseBody和ResponseEntity方法时,response在HandlerAdapte内已经被提交或者写入,意味着做任何更改太迟了—比如添加extra header。
对于这种情况,你可以实现ResponseBodyAdvice然后声明一个Controller Advice bean,直接配置在RequestMappingHandlerAdapter

1.1.7 异常

如果在request mapping过程比如 在一个@Controller中发生异常了,DispatcherServlet会委托链式的HandlerExceptionResolver的bean去处理异常,也提供默认的处理,通常是erorr response.
resolver的实现
b spring mvc详解--官方文档翻译_第6张图片

Chain of Resolvers resolver链

你可以通过声明多个HandlerExceptionResolver来构成异常链,在你的spring配置里,并且设置它的order属性。order的序号越大,resolver就会被放到越后面。
HandlerExceptionResolver具体会返回这些内容

  • a ModelAndView that points to an error view.
  • An empty ModelAndView if the exception was handled within the resolver
  • null if the exception remains unresolved, for subsequent resolvers to try, and, if the exception remains at the end, it is allowed to bubble up to the Servlet container.
Container Error Page

error page的返回
声明的error page mapping
在这里插入图片描述
以上的配置会被映射到controler逻辑
b spring mvc详解--官方文档翻译_第7张图片

1.1.8 view Resolution

Spring MVC定义了ViewResolver和view接口,提供渲染逻辑。ViewResolver提供viewname和真实views映射的能力。view路由到数据的准备到具体的view技术。
ViewResolver的实现

ViewRsolver Description
AbstractCachingViewResolver AbstractCachingViewResolver的子类,负责缓存view实例,缓存提升了查询性能。你可以设置属性cache为false来关闭。如果你在runtime必须刷新一个特定的view,你可以使用removeFromCache(String viewName, Locale loc) method.
XmlViewResolver 实现ViewResolver,来接受xml配置。默认的配置文件位置是/WEB-INF/views.xml
ResourceBundleViewResolver 实现ViewResolver,来接受bean的定义在ResourceBundle,这个bundle是基于name的。对于每个需要支持的view,需要配置[viewname].(clss)[viewname].url
UrlBasedViewResolver ViewResolver的简单实现,处理view name到urls的映射,无需清晰的定义。这种方式适用于你的viewname,匹配你的view resource,但是不能产生二义性,找到多个匹配
InternalResourceViewResolver UrlBasedViewResolver的便利子类,支持InternalResourceView(Servlets and JSPs)。其子类有JstlView and TilesView。你可以细化这个view类去生成所有views,通过是用setViewClass(..)
FreeMarkerViewResolver UrlBasedViewResolver的便捷子类,去支持FreeMarkerView
ContentNegotiatingViewResolver 实现ViewResolver接口,基于request的file name或者 Acceprt header属性
Handling

你可以链式的声明view resolvers,设置order属性可以排序,越小越执行。
ViewResolver约定,当未找到view可以返回一个null。但是在JSPs和InteralResourceViewResolver,去判定JSP是否存在的唯一方式是通过RequestDispatcher去做分发。因此你必须在relover列表的最后配置InternalResourceViewResolver
配置view解决方案和添加ViewResolver 一样容易,详见config篇。

Redirecting

重定向细节:view name的前缀让你实现重定向。URLBaseViewResolver用前缀来判定是否需要重定向。其余的的重定向URL。
网络形象是是否返回RedirectView的原因之一,但是现在可以依赖自己的prefix来判定是否需要去重定向例如(redirect:/myapp/some/resource)重定向到了当前的servlet的context,当一个名称例如redirect:https://myhost.com/some/arbitrary/path
注意如果controller如果带有@ResponseStatus,注解的值会优先于RedirectView。

Forwarding

转向forward:,UrlBasedViewResolver可以解析。这会创建一个InternalResourceView,其做了一个定向RequestDispatcher.forward()。因此不用
InternalResourceViewResolverInternalResourceView(for JSPS),但是仍旧有用。

Content Negotiation

ContentNegotiatingViewResolver不能解决views但是可以委托其他 view resolvers和选择这些view。这个委托可以从Acceptheader接受一个查询参数(例如"/path?format=pdf")
这个ContentNegotiatingViewResolver选择合适的View去处理request,比如Content-type字段,ContentNegotiatingViewResolver支持Content-typeViewResolvers的绑定。处理请求时会命中第一个ViewResolver,命中不了时,会返回DefaultViews。随后的操作是SingleTon模式的View进行渲染。
Accept Header可以包含模糊匹配
比如text/*

1.1.9 Locale

本地化,相对的是国际化。DispatcherServlet让你可以自动解决本地客户端的locale化。这部分是由LocaleResolver对象来解决的。
当request来时,DispatcherServlet去寻找local resolver,如果发现了就使用。通过使用RequestContext.getLocale()方法,你总是可以获取到本地resolver。
额外的本地化方案,你可以向handler mapping 添加额外的intercepeter去处理本地化需求。
本地化的解决包是在org.springframework.web.servlet.i18n而且配置你的应用容器用一种普通的方式。下列是Spring包含的几种resolver。

Time Zone

获取client的本地化,指导它的time zone十分有用。LocaleContextResolver接口提供一个对LocaleResolver的扩展–让resolver提供一个丰富的LocaleContext
TimeZone可以通过使用RequestContext.getTimeZone()方法获取。Time zone的信息会自动被 Date/Time的 Cpnverter和Formatter的对象所注册到。

Header Resolver

local resolver 侦测到在request中accept-language的header。通常,header 的field会包含client端本地的os系统。注意resolver不能支持time zone信息。

Cookie Resolver

本地的resolver侦测到Cookie去看Local和TimeZone是否被细化。他使用具体的细节。通过使用本地resolver的属性,你可以细化这个cookie得名称和最大时长,下列是一个例子。

Session Resolver
Locale Interceptor

b spring mvc详解--官方文档翻译_第8张图片
b spring mvc详解--官方文档翻译_第9张图片

Session Resolver

Session Resolver让你可以从session中获取LocaleTimeZone,这些可以被包含在用的请求里。和CookieLocaleResolver的差异是,这个策略本地化的选择本地setting在 Servlet container的HttpSession容器里。结果是设置只会应用到每一个session中,因此,当session结束时就会丢失。
注意无需直接和额外的session管理组件。SessionLocalResolver是和HttpSession属性一同关联在HttpServletRequest。

Locale Interceptor

你可以通过添加LocaleChangeInterceptor到一个HandlerMapping定义中去开启本地化的更改。开启后会侦测在request中的参数来直接更改本地化,即会调用在LocaleResolver中的setLoacle方法。
示例中展示调用*.view的资源,其包含了参数siteLanguage。所以示例中

1.1.10 Themes

主题的设置。theme是一系列静态资源的集合,典型的是style sheets和images,这些会影响应用的风格。

Defining a theme

去给你的Web应用使用主体,你必须去实现org.springframework.ui.context.ThemeSource接口。WebApplicationContext接口扩展了ThemeSource,但是委托给一个具体的实现。默认是org.springframework.ui.context.support.ResourceBundleThemeSource实现去加载properties文件(从classpath的root)。去使用自定义的ThemeSource或者去配置一个基于ResourceBundleThemeSource,你可以是用名称注册到Context中,Web application context会自动容器里并去使用。
当你使用ResourceBundleThemeSource的时候,主题会定义在一个简单的properties文件。
例如
b spring mvc详解--官方文档翻译_第10张图片
properties的key-values,会关联到view code中去。
默认ResourceBundleThemeSource会是用空的basename前缀。结果是properties文件会从classpath的root的去加载。因此,cool.properties主体文件放在root下就可以,例如/WEB-INF/classesResourceBundleThemeSource会使用标准的java源文件去加载组件,允许全国际化的主题。
例如/WEB-INF/classes/cool_nl.properties会被引用到一个特殊的本经图片。

Resolving Themes

如果你如前面定义了这些theme。DispatcherServlet会寻找bean名为themeResolver的bean,然后找出是用哪一个ThemeResolver。A theme resolver和LocaleResolver工作方式一样。从request中去侦测主题的选定

1.1.11. Multipart Resolver

分片 resolver。
MultipartResolverorg.springframework.web.multipartpackage中,在上传文件的时候去解析多片的请求。有 Commons FileUpload和基于Servlet 3.0的请求。
去开启多分片传输,你需要在DispatcherServlet中声明
MultipartResolverbean,名称为multipartResolver。DispatcherServlet会侦测并把它应用到即将到来的request。
当POST并使用multipart/form-data,当前的resover 会解析并包裹HttpServletRequestMultipartHttpServletRequest去解决分片。

Apache Commons FileUpload

使用Commons FileUpload,你可以配置CommonsMultipartResolver名为multipartResolver的bean。你也需要去添加这个依赖。

Servlet 3.0

Servlet 3.0的分片穿出需要在Servlet container的配置中打开。

  • 在java code中,在Servlet注册中设置MultipartConfigElement
  • 在web.xml中添加标签
    下列是如何在code中设置。
    b spring mvc详解--官方文档翻译_第11张图片

1.1.12. Logging

DEBUG级别的日志在Spring MVC被设置成友好的方式,聚焦于有价值的信息。
TRACE级别的设置原则和DEBUG级别基本一样。但是被用在打印任何输出。

敏感数据

DEBUG 和 TRACE 也许会打印敏感数据。这个为什么header和参数会被默认掩盖,但是你也可以开启他,通过在DispatcherServlet设置enableLoggingRequestDetails

你可能感兴趣的:(b spring mvc详解--官方文档翻译)