前言

随着 Spring Boot 逐渐全面笼罩到咱们的我的项目之中,咱们曾经根本忘却当年经典的 Servlet + Spring MVC 的组合,那让人相熟的 web.xml 配置。而本文,咱们想先抛开 Spring Boot 到一旁,回到从前,一起来看看 Servlet 是怎么和 Spring MVC 集成,怎么来初始化 Spring 容器的。

  • Spring MVC概述
  • 注解驱动的控制器
  • 解决办法的数据绑定
  • 试图和视图解析器
  • 本地化
  • 文件上传
  • WebSocket
  • 动态资源解决
  • 拦截器
  • 异样解决

一、Spring MVC的概述

MVC:Model + View + Controller(数据模型 + 视图 + 控制器)

三层架构

三层架构:Presentation tier + Application tier + Data tier(展现层 + 应用层 + 数据拜访层)

MVC和三层架构的关系

MVC和三层架构的关系,MVC只存在三层架构的展现层。

M理论是数据模型,是蕴含数据的对象。在Spring MVC里,有一个专门的类叫Model,用来和V之间的数据交互、传值。
V指的是视图界面,蕴含JSP、freeMarker、Velocity、Thymeleaf、Tile等。
C就是控制器(Spring MVC的注解@Controller的类)。

三层架构是整个利用的的架构,是由Spring框架负责管理的,个别我的项目构造中都由Service层、Dao层,这两个反馈在应用层和数据拜访层。

Spring MVC框架围绕DispatcherServlet这个外围开展,它负责截获申请并将其分派给相应的处理器解决。Spring MVC框架包含注解驱动控制器、申请及响应的信息处理、视图解析、本地化解析、上传文件解析、异样解决以及表单标签绑定等内容。

体系结构

Spring MVC是基于Model 2实现的技术框架。Spring MVC通过一个DispatcherServlet接管所有申请,并将具体工作委托给其余组件进行解决。

Spring MVC体系结构

  1. 客户端收回一个HTTP申请,Web应用服务器接管到这个申请,如果匹配DispatcherServlet的申请映射门路(在web.xml中指定),Web容器将该申请转交给DispatcherServlet解决。
  2. DispatcherServlet接管到这个申请后,将依据申请的信息(包含URL、HTTP办法、申请报文头、申请参数、Cookie等)及HandlerMapping的配置找到解决申请的处理器(Handler)。可将HandlerMapping看成路由控制器,将Handler看成指标主机。值得注意的是:Spring MVC中并没有定义一个Handler接口,实际上任何一个Object都能够成为申请处理器。
  3. 当DispatcherServlet依据HandlerMapping失去对应以后申请的Handler后,通过HandlerAdapter对Handler进行封装,再以对立的适配器接口调用Handler。 HandlerAdapter是Spring MVC的框架级接口,顾名思义HandlerAdapter是一个适配器,它用对立的接口对各种Handler办法进行调用。
  4. 处理器实现业务逻辑的解决后将运回一个ModelAndView给DispatcherServlet,ModelAndView蕴含了视图逻辑名和模型数据信息。
  5. ModelAndView中蕴含的是“逻辑视图名”而非真正的视图对象,DispatcherServlet借由ViewResolver实现逻辑视图名到实在视图对象的解析工作。
  6. 当失去实在的视图对象View后,DispatcherServlet就应用这个View对象对ModelAndView中的模型数据进行视图渲染。
  7. 最终客户端失去的响应音讯,可能是一个一般的HTML页而,也可能是一个XML或JSON串, 甚至是一张图片或一个PDF文档等不同的媒体模式。

《2020最新Java根底精讲视频教程和学习路线!》

配置DispatcherServlet

能够在web.xml中配置一个Servlet,并通过指定其解决的URL。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">    <!-- (1)从类门路下加载Spring配置文件-->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:application-context.xml</param-value>    </context-param>    <!-- (2)负责启动 Spring 容器的监听器,它将援用(1)处的上下文参数取得Spring配置文件的地址 -->    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <!-- (3)配置DispatcherServlet -->    <servlet>        <servlet-name>web</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <load-on-startup>1</load-on-startup>    </servlet>        <!-- (4)指定解决的URL门路 -->    <servlet-mapping>        <servlet-name>web</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping></web-app>复制代码
  1. 在(1)处,通过contextConfigLocation参数指定业务层Spring容器的配置文件(多个配置文件用,宰割)。
  2. 在(2)处,ContextLoaderListener是一个ServletLoaderListener,它通过contextConfigLocation指定的Spring配置文件启动业务层的Spring容器。
  3. 在(3)处,配置了名为web的DispatcherServlet,它默认加载/WEB-INF/web-servlet.xml(-servlet.xml)的Spring配置文件,启动Web层的Spring容器。Web层容器将作为业务层容器的子容器,Web层容器能够拜访业务层容器的Bean,而业务层容器拜访不了Web层容器的Bean。
  4. 在(4)处,通过指定DispatcherServlet解决/*全副的HTTP申请。一个web.xml能够配置多个DispatcherServlet,通过其对应的配置,让每个DispatcherServlet解决不同的申请。

DispatcherServlet 的配置参数

能够通过的属性指定配置参数:

  1.  namespace参数:DispatcherServlet对应的命名空间,默认是WEB-INF/-servlet.xml。在显式配置该参数后,新的配置文件对应的门路是WEB-INF/.xml,例如如果将namespace设置为sample,则对应的Spring配置文件为WEB-INFmple.xml。 
  2. contextConfigLocation:如果DispatcherServlet上下文对应的Spring配置文件有多个,则能够应用该属性依照Spring资源门路的形式指定,如classpath:sample1.xml,classpath:sample2.xml。
  3. publishContext:默认为true。DispatcherServlet依据该属性决定是否将WebApplicationContext公布到ServletContext的属性列表中,不便调用者可借由ServletContext找到WebApplicationContext实例,对应的属性名为DispatcherServlet#getServletContextAttributeName()的返回值。
  4. publishEvents:默认为true。当DispatcherServlet解决完一个申请后,是否须要向容器公布一个ServletRequestHandleEvent事件。

Spring容器配置

<beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd       http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context-4.0.xsd       http://www.springframework.org/schema/mvc       http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">    <context:component-scan base-package="com.ankeetc.web"/>    <!-- 会主动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean,这是SpringMVC为@Controllers散发申请所必须的 -->    <!-- 并提供了数据绑定反对、@NumberFormatannotation反对、 @DateTimeFormat反对、@Valid反对、读写XML的反对和读写JSON的反对等性能。 -->    <mvc:annotation-driven /></beans>复制代码

基于编程的配置

Spring 4.0曾经全面反对Servlet 3.0,能够应用编程的形式配置Servlet容器。在Servlet 3.0环境中,容器会在类门路中查找实现javax.servlet.ServletContainerInitializer接口的类,如果发现实现类,就会用它来配置Servlet容器。Spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又查找实现WebApplicationInitializer的类并将配置的工作交给它们来实现。Spring还提供了一个WebApplicationInitializer根底实现类AbstractAnnotationConfigDispatcherServletInitializer,使得它在注册DispatcherServlet时只须要简略地指定它的Servlet映射即可。

public class WebApplicationInitilalizer implements WebApplicationInitializer {    @Override    public void onStartup(ServletContext servletContext) throws ServletException {        ServletRegistration.Dynamic registration = servletContext.addServlet("web", new DispatcherServlet());        registration.setLoadOnStartup(1);        registration.addMapping("/");    }}复制代码

 DispatcherServlet的外部逻辑

 protected void initStrategies(ApplicationContext context) {        initMultipartResolver(context);        initLocaleResolver(context);        initThemeResolver(context);        initHandlerMappings(context);        initHandlerAdapters(context);        initHandlerExceptionResolvers(context);        initRequestToViewNameTranslator(context);        initViewResolvers(context);        initFlashMapManager(context);    }复制代码

DispatcherServlet#initStrategies()办法将在WebApplicationContext初始化后执行,此时Spring上下文中的Bean曾经初始化结束,该办法通过反射查找并拆卸Spring容器中用户自定义的Bean,如果找不到就拆卸默认的组件实例。

默认组件

在DispatcherServlet.properties配置文件里边,指定了DispatcherServlet所应用的默认组件。如果用户心愿采纳非默认的组件,只需在Spring配置文件中配置自定义的组件Bean即可。

# 本地化解析器org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver# 主题解析器org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver# 处理器解析器org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping# 处理器适配器org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter# 异样处理器org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver# 视图名称处理器org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator# 视图解析器org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolverorg.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager复制代码

DispatcherServlet拆卸各型组件的逻辑

二、注解驱动的控制器

 @RequestMapping映射申请

  1. 在POJO类上标注@Controller,再通过context:component-scan扫描到该类,能够是POJO成为一个能解决HTTP申请的控制器。
  2. 在控制器的类定义和办法定义处都能够应用@RequestMapping映射对应的解决办法。
  3. @RequestMapping岂但反对规范的URL,还反对Ant格调和{XXX}占位符的URL。
  4. @RequestMapping和value、method、params及headers别离示意申请门路、申请办法、申请参数及报文头的映射条件。

获取申请内容

  1. 能够通过@RequestParam、@RequestHeader、@PathVariable获取HTTP申请信息。
  2. 能够应用@CookieValue让办法入参绑定某个Cookie值
  3. 能够应用@MatrixVariable注解将申请中的矩阵变量绑定到处理器的办法参数中。
  4. 能够应用命令/表单对象(就是一个POJO)绑定申请参数值,Spring会依照申请参数名和对象属性名匹配的形式,主动为该对象填充属性。
  5. 能够应用Servlet API的类作为解决办法的入参,如HttpServletRequest、HttpServletResponse、HttpSession;如果应用HttpServletResponse返回相应,则解决办法返回着设置成void即可;在org.springframework.web.context.request定义了若干个可代理Servlet原生API类的接口,如WebRequest和NativeWebRequest。
  6. 能够应用java.io中的InputStream、Reader、OutputStream、Writer作为办法的入参。
  7. 还能够应用java.util.Locale、java.security.Principal作为入参。

应用HttpMessageConverter

HttpMessageConverter接口能够将申请信息转换为一个对象(类型为T),并将对象(类型为T)绑定到申请办法的参数中或输入为响应信息。DispatcherServlet默认曾经装置了RequestMethodHandlerAdapter作为HandlerAdapter组件的实现类,HttpMessageConverter即由RequestMethodHandlerAdapter应用,将申请信息转换为对象,或将对象转换为响应信息。

HttpMessageConverter的实现类

Spring为HttpMessageConverter提供了泛滥的实现类:

实现类

实现类

默认的HttpMessageConverter

RequestMappingHandlerAdapter曾经默认拆卸了以下的HttpMessageConverter:

  • StringHttpMessageConverter
  • ByteArrayHttpMessageConverter
  • SourceHttpMessageConverter
  • AllEncompassingFormHttpMessageConverter

拆卸其余类型的HttpMessageConverter

如果须要拆卸其余类型的HttpMessageConverter,能够在Spring的Web容器上下文中自行定义一个RequestMappingHandlerAdapter,注册若干HttpMessageConverter。如果在Spring web容器中显式定义了一个RequestMappingHandlerAdapter,则Spring MVC将应用它笼罩默认的RequestMappingHandlerAdapter。

应用HttpMessageConverter

  1. 能够应用@RequestBody、@ResponseBody对解决办法进行标注
  2. 能够应用HttpEntity、ResponseEntity作为解决办法的入参或返回值
RestTemplate是Spring的模板类,能够应用该类调用Web服务端的服务,它反对Rest格调的URL。
论断
  1. 当控制器解决办法应用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity 时,Spring MVC才会应用注册的HttpMessageConvertor对申请、相应音讯进行解决。
  2. 当控制器解决办法应用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity时,Spring 首先依据申请头或响应的Accept属性抉择匹配的 HttpMessageConverter,进而依据参数类型或泛型类型的过滤失去匹配的 HttpMessageConverter,若找不到可用的 HttpMessageConverter 将报错。
  3. @RequestBody、@ResponseBody不须要成对呈现。

解决XML和JSON

Spring MVC提供了几个解决XML和JSON格局的申请、响应音讯的HttpMessageConverter:

  • MarshallingHttpMessageConverter:解决XML
  • Jaxb2RootElementHttpMessageConverter:解决XML,底层应用JAXB
  • MappingJackson2HttpMessageConverter:解决JSON格局

只有在Spring Web容器中为RequestMappingHandlerAdapter拆卸好相应的HttpMessageConverter,并在交互中通过申请的Accept指定MIME类型,Spring MVC就能够是服务器段的解决办法和客户端通明的通过XML或JSON格局进行通信。

 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">        <property name="messageConverters">            <list>                <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>                <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>            </list>        </property>    </bean>复制代码

应用@RestController

@RestController曾经标注了@ResponseBody和@Controller,能够间接在控制器上标注该注解,就不必在每个@RequestMapping办法上增加@ResponseBody了。

AsyncRestTemplate

Spring 4.0提供了AsyncRestTemplate用于以异步无阻塞的形式进行服务拜访。

public class WebApplicationInitilalizer implements WebApplicationInitializer {    @Override    public void onStartup(ServletContext servletContext) throws ServletException {        ServletRegistration.Dynamic registration = servletContext.addServlet("web", new DispatcherServlet());        registration.setLoadOnStartup(1);        // 此处要设置为true        registration.setAsyncSupported(true);        registration.addMapping("/");    }}@RestControllerpublic class AsyncController {    @RequestMapping(value = "/async", method = RequestMethod.GET)    public Callable<String> async() {        System.out.println("hello!");        return new Callable<String>() {            @Override            public String call() throws Exception {                TimeUnit.SECONDS.sleep(5);                return "ASYNC";            }        };    }}public class Main {    public static void main(String[] args) {        AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();        ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.getForEntity("http://localhost:8080/async", String.class);        System.out.println("return");        future.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {            @Override            public void onFailure(Throwable ex) {                System.out.println("Failure");            }            @Override            public void onSuccess(ResponseEntity<String> result) {                System.out.println("Success");            }        });    }}复制代码

解决模型数据

Spring MVC提供了多种路径输入模型数据:

  1. ModelAndView:当解决办法返回值类型为ModelAndView时,办法体即可通过该对象增加模型数据;
  2. @ModelAttribute:在办法入参标注该注解后,入参的对象就会放到数据模型中;
  3. Map和Model:如果办法入参为org.framework.ui.Model、org.framework.ui.ModelMap、java.util.Map,当解决办法返回时,Map中的数据会主动增加到模型中;
  4. @SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个申请之间能够共享这个属性。

三、解决办法的数据绑定

Spring会依据申请办法签名的不同,将申请中的信息以肯定形式转换并绑定到申请办法的入参中,还会进行数据转换、数据格式化及数据校验等。

数据绑定流程

数据绑定

Spring MVC通过反射对指标签名进行剖析,将申请音讯绑定到解决办法的入参中。数据绑定的核心部件是DataBinder。Spring MVC主框架将ServletRequest对象及解决办法的入参对象实例传递给 DataBinder,DataBinder 首先调用拆卸在 Spring Web 上下文中的 ConversionService 组件进行数据类型转换、数据格式化等工作,将ServletRequest中的音讯填充到入参对象中, 而后调用Validator组件对己经绑定了申请音讯数据的入参对象进行数据合法性校验,最 终生成数据绑定后果BindingResult对象。BindingResult蕴含了已实现数据绑定的入参 对象,还蕴含相应的校验谬误对象。Spring MVC抽取BindingResult中的入参对象及校验谬误对象,将它们赋给解决办法的相应入参。

数据转换

类型转换模块位于org.framework.core.convert包中,同时因为历史起因,Spring还反对JDK的PropertyEditor。

ConversionService简介

ConversionService 是 Spring 类型转换体系的外围接口,它定义了以下4个办法:

  • boolean canConvert(Class sourceType, Class targetType):判断是否能够将一个Java类转换为另一个Java类。
  • Boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType):需转换的类将以成员变量的形式呈现在宿主类中。TypeDescriptor岂但形容了需转换类的信息,还形容了从宿主类的上下文信息,如成员变量上的注解,成员变量是否以数组、汇合或Map的形式出现等。类型转换逻辑能够利用这些信息做出 各种灵便的管制。
  • T convert(Object source, Class targetType):将原类型对象转换为指标类型对象。
  • Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType):
    将对象从原类型对象转换为指标类型对象,此时往往会用到所在宿主类的高低 文信息。

第一个和第三个接口办法相似于PmpertyEditor,它们不关注类型对象所在的上下文 信息,只简略地实现两个类型对象的转换,惟一的区别在于这两个办法反对任意两个类型的转换。而第二个和第四个接口办法会参考类型对象所在宿主类的上下文信息,并利用这些信息进行类型转换。

应用ConversionService

能够利用 org.springframework.context.support.ConversionServiceFactoryBean 在 Spring 的 上下文中定义一个ConversionService。Spring将自动识别出上下文中的ConversionService, 并在Bean属性配置及Spring MVC解决办法入参绑定等场合应用它进行数据转换。该FactoryBean创立ConversionService内建了很多转换器,可实现大多数Java类型的转换工作。除了包含将String对象转换为各种根底类型的对象外,还包含String、 Number、Array、Collection、Map、Properties 及 Object 之间的转换器。可通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器:

 <bean class="org.springframework.context.support.ConversionServiceFactoryBean">        <property name="converters">            <list>                <bean class="com.ankeetc.MyConverter"/>            </list>        </property>    </bean>复制代码

Spring反对的转换器

Spring 在 org.springframework.core.convert.converter 包中定义了3种类型的转换器接口,实现任意一个转换器接口都能够作为自定义转换器注册到ConversionServiceFactoryBean中。这3种类型的转换器接口别离为:

  • Converter<S, T>:将S类型的对象转换为T类型的对象
  • GenericConverter:依据源类对象及指标类对象所在的宿主类的上下文信息进行类型转换工作。该类还有一个子接口ConditionalGenericConverter,它增加了一个接口办法依据源类型及指标类型所在宿主类的上下文信息决定是否要进行类型转换。
  • ConverterFactory:

ConversionServiceFactoryBean 的 converters 属性可承受 Converter、ConverterFactory、 GenericConverter或ConditionalGenericConverter接口的实现类,并把这些转换器的转换逻辑对立封装到一个 ConversionService 实例对象中(GenericConversionService)。Spring 在Bean属性配置及Spring MVC申请音讯绑定时将利用这个ConversionService实例实现类型转换工作。

在Spring中应用@lnitBinder 和 WebBindingInitializer拆卸自定义编辑器

Spring也反对JavaBeans的PropertyEditor。能够在控制器中应用@InitBinder增加自定义的编辑器,也能够通过 WebBindingInitializer 拆卸在全局范畴内应用的编辑器。

 @InitBinder    public void initBinder(WebDataBinder binder) {        binder.registerCustomEditor(User.class, new PropertyEditorSupport() {            @Override            public void setAsText(String text) throws IllegalArgumentException {                User user = new User();                user.setName(text);                this.setValue(user);            }        });    }复制代码

如果心愿在全局范畴内应用,则可实现WebBindingInitializer接口并在该实现类中注册。

  1. 实现WebBindingInitializer接口并在initBinder接口办法中注册了自定义的编辑器。
  2. 在 Spring 上下文中通过 RequestMappingHandlerAdapter 拆卸自定义的Initializer。

程序

对于同一个类型对象来说,如果既在ConversionService中拆卸了自定义转换器,又通过WebBindinglnitializer拆卸了自定义编辑器,同时还在控制器中通过@InitBinder装 配了自定义编辑器,那么Spring MVC将按以下优先程序查找对应类型的编辑器:

  1. 查问通过@InitBinder拆卸的自定义编辑器。
  2. 查问通过ConversionService拆卸的自定义转换器。
  3. 查问通过WebBindingInitializer拆卸的自定义编辑器。

数据格式化

Spring的转换器并不提供输出及输入信息格式化的工作,个别须要转换的源类型数据(个别是字符串)都是具备肯定格局的,在不同的本地化环境中, 同一类型的数据还会相应地出现不同的显示格局。Spring引入了一个新的格式化框架,这个框架位于org.springframework.format类包中。

最重要的 Formatter接口
注解驱动格式化AnnotationFormatterFactory

为了让注解和格式化的属性类型关联起来,Spring在Formatter所在的包中还提供了一个 AnnotationFormatterFactory接口。

启用注解驱动格式化性能

对属性对象的输出/输入进行格式化,从实质上讲仍然属于“类型转换”的领域。 Spring就是基于对象转换框架植入“格式化”性能的。Spring 在格式化模块中定义了一个实现 ConversionService 接口的 FormattingConversionService实现类,该实现类扩大了 GenericConversionService,因而它既具备类型转换性能,又具备格式化性能。
FormattingConversionService 也领有一个对应的 FormattingConversionServiceFactoryBean 工厂类,后者用于在Spring上下文中结构一个FormattingConversionService。通过这个工厂类,既能够注册自定义的转换器,还能够注册自定义的注解驱动逻辑。因为 FormattingConversionServiceFactoryBean 在外部会主动注册 NumberFormatAnnotationFormatterFactory 和 JodaDateTimeFormatAnnotationFormatterFactory,因而拆卸了 FormattingConversionServiceFactoryBean 后,就能够在 Spring MVC 入参绑定及模型数据输入时应用注解驱动的格式化性能。
值得注意的是,mvc:annotation-driven/标签外部默认创立的ConversionService实例就是一个 FormattingConversionServiceFactoryBean。

数据校验

Spring领有本人独立的数据校验框架,同时反对JSR-303规范的校验框架。Spring 的DataBinder在进行数据绑定时,可同时调用校验框架实现数据校验工作。在Spring MVC中,则可间接通过注解驱动的形式进行数据校验。
LocalValidatorFactoryBean 既实现了 Spring 的 Validator 接口,又实现了 JSR-303 的 Validator 接口。只有在 Spring 容器中定义了一个 LocalValidatorFactoryBean,即可将其注入须要数据校验的Bean中。值得注意的是,Spring自身没有提供JSR-303的实现,所以必须将JSR-303的实现 者(如Hibernate Validator)的JAR文件放到类门路下,Spring将主动加载并拆卸好 JSR-303的实现者。
mvc:annotation-driven/会默认拆卸一个 LocalValidatorFactoryBean,通过在解决办法的入参上标注@Valid注解,即可让Spring MVC在实现数据绑定后执行数据校验工作。

四、视图和视图解析器

五、本地化

Spring提供了以下4个本地化解析器。

  • AcceptHeaderLocaleResolver:依据 HTTP 报文头的 Accept-Language 参数确定本 地化类型。如果没有显式定义本地化解析器,则Spring MVC默认采纳 AcceptHeaderLocaleResolver。
  • CookieLocaleResolver:依据指定的Cookie值确定本地化类型。
  • SessionLocaleResolver:依据Session中特定的属性值确定本地化类型。
  • LocaleChangeInterceptor:从申请参数中获取本次申请对应的本地化类型。

六、文件上传

Spring MVC为文件上传提供了间接反对,这种反对是通过即插即用的MultipartResolver 实现的。Spring 应用 Jakarta Commons FileUpload 技术实现了一个 MultipartResolver 实现 类:CommonsMultipartResolver。
在Spring MVC上下文中默认没有拆卸MultipartResolver,因而默认状况下不能 解决文件的上传工作。如果想应用Spring的文件上传性能,则须要先在上下文中配置 MultipartResolver。

七、WebSocket

八、动态资源解决

  1. mvc:default-servlet-handler/:在 smart-servlet.xml 中配置mvc:default-servlet-handler/后,会在 Spring MVC 上下文中定义一个 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它将充当一个检查员的角色,对进入DispatcherServlet的URL进行筛查。如果发现是动态资源的申请,就将该申请转由Web应用服务器默认的Servlet解决;如果不是动态资源 的申请,则由DispatcherServlet持续解决。
  2. mvc:resources/:mvc:default-servlet-handler/将动态资源的解决经由Spring MVC框架交回Web应 用服务器。而mvc:resources/更进一步,由SpringMVC框架本人解决动态资源,并添 加一些有用的附加性能。

九、拦截器

当收到申请时,DispatcherServlet将申请交给处理器映射(HandlerMapping),让它找出对应该申请的HandlerExecutionChain对象。在解说HandlerMapping之前,有必要 认识一下这个 HandlerExecutionChain 对象。

HandlerExecutionChain

HandlerExecutionChain负责解决申请并返回ModelAndView的解决执行链,它蕴含一个解决该申请的处理器 (Handler),同时包含若干个对该申请施行拦挡的拦截器(HandlerInterceptor)。当 HandlerMapping 返回 HandlerExecutionChain 后,DispatcherServlet 将申请交给定义在 HandlerExecutionChain中的拦截器和处理器一并处理。
位于处理器链末端的是一个 Handler,DispatcherServlet通过 Handler Adapter适配器对 Handler进行封装,并按对立的适配器接口对 Handler解决办法进行调用。能够在 web-servlet.xml中配置多个拦截器,每个拦截器都能够指定一个匹配的映射门路,以限度拦截器的作用范畴。

十、异样解决

Spring MVC通过 HandlerExceptionResolver处理程序的异样,包含处理器映射、数据绑定及处理器执行时产生的异样。 HandlerExceptionResolver仅有一个接口办法:Modelandview resolveException(HttpServletRequest request HttpServletResponse response Object handler, Exception ex)。当产生异样时,Spring MVC将调用 resolveException办法,并转到 ModelAndView 对应的视图中,作为一个异样报告页面反馈给用户。

实现类

HandlerExceptionResolver领有4个实现类

  1. DefaultHandlerExceptionResolver:默认拆卸了该类,将对应异样转换为错误码
  2. SimpleMappingExceptionResolver:对所有异样进行对立解决
  3. AnnotationMethodHandlerExceptionResolver:默认注册了该类,容许通过@ExceptionHandler注解指定解决特定的异样
  4. ResponseStatusExceptionResolver

文章到这里就完结了

小编这里总结一份springMVC的思维导图,想理解的小伙伴能够看看呢

链接:https://juejin.cn/post/690223...