本文已参与「新人创作礼」活动,一起开启掘金创作之路。
@[TOC]
1.几个模块
整个从用户的发送的请求到最后处理流程,包含如下几大模块。
1.中央调度器DispatcherServlet
2.处理器映射器HandleMapping
3.处理器适配器HandleAdapter
4.处理器Controller
5.视图解析器ViewResolver
6.视图View
2.处理流程
先放一张图:
1.用户发起请求/hello
2.DispatcherServlet中央调度器接收请求,转交给处理映射器
处理映射器:实现HandleMapping接口的 都是映射器。
处理器映射器作用: 负责把请求从容器中获取处理器对象Controller,并交给Controller响应方法处理。
框架找到处理器对象(@Controller标注的)把它放入一个处理器执行链(HandleExcutionChain)。
HandleExcutionChain:存放处理器,和拦截器Interceptor。
3.DIspatcherServlet将2中的处理器对象交给处理器适配器(HandleAdapter).
处理器适配器:springmvc中的对象,需要实现HandleAdapter对象。
处理适配器作用:执行处理器Controller的方法 返回视图ModelAndView
4.视图解析器解析得到视图
视图解析器:springMVC中对象,需要实现ViewResolver接口
视图解析器作用:组成完整视图路径,前缀后缀方式。
6.中央调度器将视图View返回用户
3.拦截器介绍
拦截器和过滤器不一样,过滤器是Servlet对象,是在web.xml里面创建,用于过滤静态资源的html,css,js等,还会设置一些字符集编码工作。
拦截器是拦截用户的controller请求的,会被DispatcherServlet接管。
1.拦截器的执行时间
拦截器HandleInterceptor有三个方法。
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
preHandle:
用户的请求被DispatcherServlet接管转发给处理器映射器HandleMapping处理之后,找到处理器,在运行处理器Controller方法之前先执行拦截器HandleInterceptor的preHandle方法。
postHandle:
在处理器适配器执行完处理器Controller方法之后,在返回的ModelAndView之前可以修改视图相关的数据。
所以这个方法有个参数是ModelAndView
afterCompletion:
最后视图controller方法执行完了视图也返回了,才执行。
一般用来计算用户发送请求开始到后台执行处理结束的时间。
2.拦截器实际使用
一般是用于拦截所有的请求,用于登录判定,没有登录就会被拦截,登录之后放行,然后执行相应的处理器Controller方法。
拦截器创建步骤:
1.创建拦截器 实现HandleInterceptor接口
2.实现WebMvcConfigure接口,声明拦截器。
1.创建拦截器
/*
拦截器
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功后获取session,如果获取不了,就返回/login
Object loginUser = request.getSession ().getAttribute ("loginUser");
if(loginUser==null){
request.setAttribute ("msg", "没有登录权限!请重新登录!");
request.getRequestDispatcher ("/login").forward (request, response);
return false;
}else{
return true;
}
}
}
2.声明拦截器
@Configuration
public class MyMVCconfig implements WebMvcConfigurer {
//登录拦截器
//拦截所有的请求 exclude排除/index /login /index/login static/** 这些不被拦截
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor (new LoginHandlerInterceptor ()).addPathPatterns ("/**").excludePathPatterns ("/index/login","/","/index","/login","/css/**","/images/**","/js/**","/assets/**");
}
}
拦截器在springboot中一般不这样搞,因为有安全框架spingsecurity和shiro。