今天来回顾下Spring MVC中那些基础的概念和一些重要的组件。
SpringMVC采用了”前端控制器”的设计模式,即采用了一个”前端控制器”来响应请求、调用controller、将model交给渲染器、接着返回响应。
spring MVC流程
- DispatcherServlet接受客户端http请求
- DispatcherServlet向控制器映射HandlerMapping根据request获取对应的handlerExecutionChain
- 包括了handler(controller)
- interceptorList(拦截器列表)
- DispatcherServlet通过适配器HandlerAdapter调用Handler(控制器Controller)
- Handler处理业务逻辑,返回ModelAndView
- DispatcherServlet得到Handler返回结果ModelAndView
- DispatcherServlet把ModelAndView传给ViewResolver处理获得view
- DispatcherServlet调用view.render对model渲染
- 视图渲染完毕,返回response给客户端
拦截器
拦截器主要用于拦截用户请求,并作出相应的处理。目前项目中经常用拦截器来做http请求的日志记录、用户鉴权等工作。它有如下两种方式实现:
实现HandlerInterceptor接口
HandlerInterceptor是在spring.web.servlet包下的接口,它主要定义了3个方法,分别是preHandle, postHandle和 afterCompletion。
- preHandle: 该方法会在控制器方法前执行,如果为true则继续执行,否则中断。
- 判断登陆:可以在该方法中获取到request的header,从而拿到token和userId来判断是否登陆。
- 日志:也可以在该方法中使用ThreadLocal来记录当前请求的开始时间,从而统计一个请求处理的时长。
- postHandle: 该方法在控制器方法后调用之后,解析视图之前执行。
- 日志:可以记录modelAndView中的viewName,来判断是否找到了正确的modelAndView。
- afterCompletion: 该方法在视图解析完成后执行。
- 日志:计算处理时长
- 资源:资源清理
WebMvcConfigurer配置
HandlerInterceptor接口实现后,需要实现WebMvcConfigurer,并在其实现类中将已经实现好的HandlerInterceptor添加进去,同时可以使用excludePathPatterns或addPathPatterns方法来控制拦截的url路径。
执行顺序
整个Interceptor的执行流程是:Interceptor.preHandle->HandleAdapter.handle->Interceptor.postHandle->DispatcherServlet.render->Interceptor.afterCompletion。
对于多个Interceptor的情况,会按照配置的先后顺序来执行对应的方法。其中,preHandle与配置顺序相同,postHandle和afterCompletion与配置顺序相反。
注意和javax.servlet.filter使用时,filter是先执行,随后走interceptor。
常用注解和注意事项
- @Controller:控制器注解,以控制器形式被IoC容器管理
- @RequestMapping:用于拦截某个url到某个controller或方法上,配合method=RequestMethod.XXX,params=”param=xxx”
- @ResponseBody:返回体按照json格式返回,且不作为ModelAndView
- Controller方法入参可以定义HttpServletRequest作为参数,来获取request中的信息,比如request.getParameterMap获取参数map
参考: