SpringMVC
【黑马程序员2022新版SSM框架教程_Spring+SpringMVC+Maven高级+SpringBoot+MyBatisPlus企业实用开发技术】
10 拦截器
文章目录
- SpringMVC
- 10 拦截器
- 10.3 拦截器参数
- 10.3.1 前置处理方法
- 10.3.2 后置处理方法
- 10.3.3 完成处理方法
- 10.4 拦截器链配置
- 10.4.1 配置多个拦截器
10.3 拦截器参数
10.3.1 前置处理方法
原始方法之前运行preHandle
- request:请求对象
- response:响应对象
- handler:被调用的处理器对象,本质上是一个方法对象,对反射中的Method对象进行了再包装
使用request对象可以获取请求数据中的内容,如获取请求头的Content-Type
//原始方法调用前执行的内容
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String contentType = request.getHeader("Content-Type");
System.out.println("preHandle..." + contentType);
return true;
}
使用handler参数,可以获取方法的相关信息
//原始方法调用前执行的内容
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String contentType = request.getHeader("Content-Type");
HandlerMethod handlerMethod = (HandlerMethod) handler;
String methodName = handlerMethod.getMethod().getName();
System.out.println("preHandle..." + contentType + " " + methodName);
return true;
}
10.3.2 后置处理方法
原始方法运行后运行,如果原始方法被拦截,则不执行
前三个参数和preHandle的是一致的
modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整
现在都是返回JSON 数据,所以这个参数的使用率不高
10.3.3 完成处理方法
拦截器最后执行的方法,无论原始方法是否执行
前三个参数与上面的是一致的。
ex:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理
有了全局异常处理器类,所以这个参数的使用率也不高
这三个方法中,最常用的是preHandle,在这个方法中可以通过返回值来决定是否要进行放行,开发者可以把业务逻辑放在该方法中,如果满足业务则返回true放行,不满足则返回false拦截。
10.4 拦截器链配置
目前,在项目中只添加了一个拦截器,如果有多个,该如何配置?配置多个后,执行顺序是什么?
10.4.1 配置多个拦截器
① 步骤1 创建拦截器类
实现接口,并重写接口中的方法
package com.dingjiaxiong.controller.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* ClassName: ProjectInterceptor2
* date: 2022/9/19 18:14
*
* @author DingJiaxiong
*/
@Component
public class ProjectInterceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...222");
return true; //放行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...222");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...222");
}
}
② 步骤2 配置拦截器类
package com.dingjiaxiong.config;
import com.dingjiaxiong.controller.interceptor.ProjectInterceptor;
import com.dingjiaxiong.controller.interceptor.ProjectInterceptor2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* ClassName: SpringMvcConfig
* date: 2022/9/19 16:56
*
* @author DingJiaxiong
*/
@Configuration
@ComponentScan({"com.dingjiaxiong.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Autowired
private ProjectInterceptor2 projectInterceptor2;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
}
}
③ 运行程序,观察顺序
可以看到拦截器执行的顺序是和配置顺序有关。【先进后出】
- 当配置多个拦截器时,形成拦截器链
- 拦截器链的运行顺序参照拦截器添加顺序为准
- 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
- 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作
- preHandle:与配置顺序相同,必定运行
- postHandle:与配置顺序相反,可能不运行
- afterCompletion:与配置顺序相反,可能不运行
【以运行结果为准】