在Spring Boot中,你可以使用拦截器(Interceptor)和过滤器(Filter)来对请求进行拦截和处理。虽然它们的目标相似,但在实现和使用上存在一些区别。
1.拦截器(Interceptor)
在Spring Boot中,拦截器是基于Spring MVC框架的一部分,主要用于对控制器方法进行拦截处理。
拦截器是通过实现HandlerInterceptor接口来定义的
其中包括三个主要方法:preHandle、postHandle和afterCompletion。
1.preHandle方法在进入控制器方法之前执行
2.postHandle方法在控制器方法执行后、渲染视图之前执行
3.afterCompletion方法在渲染视图之后执行。
1-1.Springboot实现拦截器方法。
首先拦截器是基于MVC框架的
其中org.springframework:spring-webmvc依赖,有个HandlerInterceptor拦截器的接口类。
1.新建一个实现类继承HandlerInterceptor接口,并且重写接口类里面的三个方法
public class UserInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
System.out.println("=======拦截器=======");
String referer = "";
if (request.getHeader("referer") != null) {
referer = request.getHeader("referer");
int index = referer.indexOf("?");
if (index != -1) {
referer = referer.substring(0, index);
}
System.out.println(referer);
System.out.println(request.getRequestURI());
// 这里做拦截处理,和开放处理。
// 一般情况下是校验用户session来拦截未带session的请求,这里做开放不带session的api请求
// 这里做个示例。拦截和放行都写一下。
// 原理非常简单,你return的值为true就是放行,返回false则为拦截
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
// 如果请求类型是预检,就放行。流程很简单,举一反三即可
return true;
}
// 如果引号里的UIR等于request.getRequestURI。就设置响应值,返回false拦截该请求
if ("".equals(request.getRequestURI())) {
System.out.println("此api占未开放");
// 设置响应的内容类型
response.setContentType("application/json");
// 设置响应的字符编码
response.setCharacterEncoding("UTF-8");
// 获取响应输出流
PrintWriter writer = response.getWriter();
// 向响应体中写入内容
writer.println(RespResult.error404("此api占未开放"));
// 关闭输出流
writer.close();
return false;
}
// 这里可以写其他关于session的操作。
return true;
}
}
拦截器写完后是无法使用的。需要注册拦截器并且注入Springboot。
注册拦截器也是基于MVC框架的,所以先建一个类继承WebMvcConfigurer接口,并且重写addInterceptors方法
// 这里需要加上@Configuration定义配置类
// 用于构建bean定义,初始化Spring容器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println(registry);
// 这里直接new一个我们的拦截器类。用于注册即可。
registry.addInterceptor(new UserInterceptor());
}
}
到这里拦截器就可以正常使用,仔细看还是很简单的。
2.过滤器(Filter)
过滤器是基于Servlet规范的一部分,可以在请求到达Servlet容器时对其进行预处理和后处理。
过滤器是通过实现javax.servlet.Filter接口来定义的,其中包括一个doFilter方法。
doFilter方法在请求进入Servlet之前执行,并且可以对请求进行修改、过滤或者增强。
过滤器可以对请求和响应进行操作,但无法直接访问处理方法中的具体对象或结果。
2-1.Springboot实现过滤器方法。
过滤器是通过javax.servlet.Filter接口定义。先创建个实现类继承Filter接口
// 注意加上注解@Component
@Component
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化过滤器 启动项目会执行这个方法
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 调用请求会执这个方法
// 这里主要做一下请求的头部过滤等,也可以做自己的处理
System.out.println("==========执行过滤器===========");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:XXXX");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization,access-token, Accept,X-Requested-With");
response.setHeader("Access-Control-Allow-Credentials", "true");
// 处理预检请求
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
// 请求结束会执行这个方法
}
}
注意,过滤器写完后需要在Springboot的Application启动类的main方法自动注册过滤器。写入注解即可。
@SpringBootApplication
// 需要写入注解@ServletComponentScan,用于自动注册过滤器
@ServletComponentScan
@CrossOrigin //前后端进行跨域操作
public class XXXXApplication {
public static void main(String[] args) {
//启动
SpringApplication.run(YxilffApplication.class);
}
}
做完这些就已经可以启动项目测试了。