您的位置:首页 > 编程语言 > Java开发

Springboot整合过滤器(Filter)和拦截器(Interceptor)

2020-07-12 17:12 519 查看

前言
        过滤器和拦截器,说到他俩,不得不对比一下,先来说说他俩的区别以及执行的先后顺序问题。

区别
  •         适用范围不同:Filter是Servlet规范规定的,只能用于Web程序中。而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。
  •         规范不同:Filter是在Servlet规范中定义的,是Servlet容器支持的。而拦截器是在Spring容器内的,是Spring框架支持的。
  •         使用的资源不同:同其他的代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IOC注入到拦截器即可;而Filter不能。
  •         深度不同:Filter旨在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后能,因此拦截器的使用具有更大的弹性。所以在Spring架构的程序中,要优先使用拦截器。
  •         触发时间不同:请求通过Tomcat > Filter > Servlet > Interceptor >Controller,由此可见,过滤器先触发,拦截器后触发

流程图

使用情况

过滤器的实现基于回调函数。 而拦截器(代理模式)的实现基于反射,代理分静态代理和动态代理,动态代理是拦截器的简单实现。

         何时使用拦截器?何时使用过滤器?

  •         如果是非spring项目,那么拦截器不能用,只能用过滤器。
  •         如果是处理controller前后,既可以使用拦截器也可以使用过滤器。
  •         如果是处理dispatcherServlet前后,只能使用过滤器。

过滤器的基本使用方法

        方法一:
                1、 创建FirstFilter类并实现Filter接口
                        注意:该接口是javax.servlet包下的
                2、 重写方法
                        注意:Filter属于Servlet的子技术,所以启动类@ServletComponentScan注解可以扫描到此@WebFilter的类。

package com.example.demo.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//配置拦截信息
@WebFilter(filterName = "ControlFilter",urlPatterns = {"/*"})
public class ControlFilter implements Filter {
public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//...逻辑操作
//放行
chain.doFilter(req, resp);
}

public void init(FilterConfig config) throws ServletException {

}

}

        在启动器类中添加扫描Filter类的注解@ServletComponentScan

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@MapperScan("com.example.demo.mapper")
//扫描WebFilter注解
@ServletComponentScan
public class RaiseApplication {

public static void main(String[] args) {
SpringApplication.run(RaiseApplication.class, args);
}

}

拦截器的基本使用方法

        创建MyHandlerInterceptor类,然后实现HandlerInterceptor接口,重写 preHandle()方法

package com.example.demo.Interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class MyHanderInterceotor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//简单判断用户是否登录
HttpSession session=request.getSession();
Object ob=session.getAttribute("userIsNull");
if(ob==null){
return false;
}
System.out.println(3);
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}
}

        到这儿还没完,Springboot不知道这里是拦截器,接下来还需要Springboot和MyHandlerInterceptor的关系。创建InterceptorConfig类,内容如下:

package com.example.demo.config;

import com.core.raise.Interceptor.MyHanderInterceotor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;
//添加Springboot配置扫描注解,该注解会在Springboot项目启动的时候被加载
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截路径
List<String> list=new ArrayList<>();
list.add("/*");
List<String> list2=new ArrayList<>();
list2.add("/toLogin");
list2.add("/toAddUser");
registry.addInterceptor(new MyHanderInterceotor())
.addPathPatterns(list)//指定黑名单,只要匹配到路径就运行拦截器的方法
.excludePathPatterns(list2);//指定白名单,直接绕过拦截器
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: