1. 处理流程
- 请求提交给
DispatchServlet - 查找
HandlerMapping - 调用由
HandlerAdapter封装后的Handler - 返回
ModelAndView到DispatcherServlet - 借由
ViewResolver完成逻辑视图到真实视图的转换 - 返回响应
2. 配置 DispatcherServlet
web.xml
1 | <web-app> |
- 子容器可以访问父容器的 bean,父容器不能访问子容器的 bean
- 默认采用
org.springframework.web.context.ContextLoaderListener - 默认使用
/WEB-INF/{servlet-name}-*.xml加载子容器
3. DispatcherServlet 的初始化
DispatcherServlet初始化
1 | protected void initStrategies(ApplicationContext context) { |
- 默认配置:
DispatcherServlet.properties
1 | # Default implementation classes for DispatcherServlet's strategy interfaces. |
4. Controller 注解
4.1 类注解
@Controller(由 Spring 识别Handler实例)@RequestMapping(value=, method=, params=)
4.2 方法注解
@RequestMapping(value=, method=, params=)@PathVariable,配合占位符{parameter}@RequestParam(value=, required=, defaultValue=)@CookieValue(value=, required=, defaultValue=)@RequestHeader(value=, required=, defaultValue=)
5. 封装入参
HttpServletRequest,WebRequest,ServletRequest的InputStream/ReaderHttpServeltResponse,ServletResponse的OutputStream/Writer
6. 请求信息和对象的转换
6.1 基本
HttpMessageConverter<T>- 使用
@RequestBody/@ResponseBody;使用HttpEntity<T>/ResponseEntity<T> - Spring 根据 HTTP 报文头部的
Accept指定的 MIME 类型,查找匹配的HttpMessageConverter - Spring MVC 默认装配
AnnotationMethodHandlerAdapter,调用HttpMessageConverter - MVC 命名空间的
<mvc:annotation-driven/>标签会创建并注册一个默认的DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例,如果上下文中存在自定义的对应组件 bean,则覆盖默认配置
6.2 样例
app-servlet.xml
1 | <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> |
7. 处理模型数据
- Spring MVC 在调用方法前会创建一个隐含的模型对象
ModelAndView:返回值类型为ModelAndView时,方法体通过该对象添加模型数据@ModelAttribute:入参对象添加到数据模型中- Map 和 Model:入参为
org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map时,处理方法返回时,Map 中的数据会自动添加到模型中 @SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求共享
8. 数据绑定
8.1 基本
- Spring MVC 将
ServletRequest对象及处理方法的入参实例传递给DataBinder; DataBinder调用ConversionService组件进行数据类型转换、数据格式化等工作,将ServletRequest中的消息填充到入参对象中;- 然后再调用
Validator组件对已经绑定了请求消息数据的入参对象进行数据合法性校验,并最终生成绑定结果BindingResult对象,其中还包含相应的校验错误对象 - 抽取
BindingResult中的入参对象及校验错误对象,赋给处理方法的相应入参
8.2 数据转换
- 例如:将请求信息中A类型参数转换并绑定到 Controller 对应的处理方法的 B 类型入参中
- 基于
ConversionService接口,Spring 将自动识别其实现类,用于入参类型转换,类似于 C++ 中的自定义类型转换。例如,将 HTTP 请求信息中的字符串格式参数转换为 Controller 对应方法中的类类型入参 - 可通过
ConversionServiceFactoryBean的converters属性注册自定义转换器。可接受Converter,ConverterFacotory,GenericConverter或ConditionalConverterFactory的实现类,并统一封装到一个ConversionService的实例(即GenericConversionService)中
1 | <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> |
<mvc:annotation-driven/>标签还会注册一个默认的ConversionService,即FormattingConversionServiceFactoryBean
8.3 数据格式化
- 例如:将请求信息中字符串类型参数转换并绑定到 Controller 对应的处理方法入参中的 Date 类型属性中
- 格式化框架定义了
Formatter<T>接口,扩展于Printer<T>和Parser<T>接口 - Srping 提供
AnnotationFormatterFactory<A extends Annotation>接口及两个实现类:NumberFormatAnnotationFormatterFactory和JodaDateTimeFormatAnnotationFormatterFactory - 在入参类属性上使用注解:
@DateTimeFormat,@NumberFormat - Spring 通过
<mvc:annotation-driven/>标签创建FormattingConversionServiceFactoryBean作为FormattingConversionService的实例,自动装配NumberFormatAnnotationFormatterFactory和JodaDateTimeFormatAnnotationFormatterFactory
8.4 数据验证
<mvc:annotation-driven/>标签会默认装配LocalValidatorFactoryBean,实现了 Spring 的Validator接口,通过在入参上标注@Valid注解即可让 Spring 在完成数据绑定后执行数据校验@Valid注解标注的入参和其后的BindingResult或Errors入参成对出现,后者保存前者的校验结果- 校验结果也保存在 MVC 的隐含模型中
- 样例
1 | public Class User { |
9. 视图解析
9.1 基本
- 视图对象是一个 bean,由视图解析器负责实例化。
- 不同的视图实现技术对应于不同的
View实现类 - 所有的视图解析器都实现了
ViewResolver接口
9.2 样例
app-servlet.xml
1 | <!-- For multipart encoding support --> |
10. 静态资源处理
- 需要对项目中的图片、html 静态资源等单独处理
- 配置
<mvc:default-servlet-handler>后,会装配一个DefaultServletHttpRequestHandler,对静态资源做检查 - 配置
<mvc:resources/>,允许对静态资源文件路径作映射,并提供文件在浏览器端的缓存控制,例如
1 | <mvc:resources mapping="/resources/**" location="/,classpath:/META-INF/publicResources" /> |
11. 拦截器
11.1 基本
DispatcherServlet将请求交给处理器映射(HandlerMapping),找到对应的HandlerExecutionChain- 找到对应的
HandlerExecutionChain包含若干HandlerInterceptor,和一个Handler HandlerInterceptor接口:
1 | public interface HandlerInterceptor { |
11.2 样例
app-servlet.xml:
1 | <mvc:interceptors> |
12. 异常处理
12.1 基本
- Spring MVC 通过
HandlerExceptionResolver处理异常 HandlerExceptionResolver接口:
1 | public interface HandlerExceptionResolver { |
- Spring MVC 默认装配了
DefaultHandlerExceptionResolver - Spring MVC 默认注册了
AnnotationMethodHandlerExceptionResolver,允许通过@ExceptionHandler指定处理特定异常
12.2 样例
web.xml
1 | <web-app> |