springboot 拦截器与过滤器

    技术2022-07-17  78

    过滤器(Filter)与拦截器()主要区别包括以下几个方面:

    Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。

    Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行。

    Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,使用更方便。

     

    拦截器

    自定义拦截器

      /**   通过路径进行权限拦截   */   @Component   public class PermissionInterceptor implements HandlerInterceptor {         @Autowired       private RedisComponent redisComponent;         //preHandle是在请求执行前执行的       @Override       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {           String token = request.getRemoteUser();           if (StringUtils.isEmpty(token)){               throw new AuthorityException();           }           ShareManagerPO shareManagerPO = (ShareManagerPO)redisComponent.getValue(token, ShareManagerPO.class);           String requestURI = request.getRequestURI();           List<PermissionPO> permissionList = shareManagerPO.getPermissionList();           ArrayList<String> urls = new ArrayList<>();           for (PermissionPO permissionPO : permissionList) {               urls.add(permissionPO.getPath());           }           int indexOf = requestURI.lastIndexOf("/");           String substring = requestURI.substring(1,indexOf);           if (urls.contains(substring)){               return true;           }else {               throw new AuthorityException();           }       }       @Override       public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {       }       @Override       public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {         }   }

    拦截器的配置

    ```java @Configuration public class PermissionConfig implements WebMvcConfigurer {       @Autowired     PermissionInterceptor permissionInterceptor;       @Override     public void addInterceptors(InterceptorRegistry registry) {         //指定拦截器,指定拦截路径         registry.addInterceptor(permissionInterceptor).addPathPatterns("/**")                 //不被拦截的路径                 .excludePathPatterns("/shareManager/**")                 .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");       }       //配置不被拦截的静态资源     @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/swagger-ui.html")                 .addResourceLocations("classpath:/META-INF/resources/");           registry.addResourceHandler("/webjars/**")                 .addResourceLocations("classpath:/META-INF/resources/webjars/");       } } ```

    过滤器

    过滤器(Filter)是Servlet中常用的技术,可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,常用的场景有登录校验、权限控制、敏感词过滤

    下面是springboot项目利用过滤器来获取登录成功用户的信息

    GenericFilterBean 只需要在自定义类中重写doFilter方法

    public class TokenAuthenticateFilter extends GenericFilterBean {    private BaseTokenAuth service; ​    public TokenAuthenticateFilter(BaseTokenAuth service) {        this.service = service;   } ​    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {        Authentication authentication = service.getAuthentication((HttpServletRequest) request);        //存放authentication到SecurityContextHolder   存储用户信息        SecurityContextHolder.getContext().setAuthentication(authentication);        filterChain.doFilter(request, response);   } }

    一、@WebFilter注解方式

    使用@WebFilter注解为声明当前类为filter,第一个参数为该filter起一个名字,第二个参数为说明要拦截的请求地址,当前类需要实现Filter接口,里面有三个方法,分别为过滤器初始化、过滤方法和过滤器销毁。

    @Slf4j @WebFilter(filterName = "myFilter1", urlPatterns = "/*") public class MyFilter1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info(filterConfig.getFilterName() + " init"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { log.info("myFilter1 begin"); try {  log.info("业务方法执行");  chain.doFilter(request, response); } catch (Exception e) {  log.error("error!", e); } log.info("myFilter1 end"); } @Override public void destroy() { } }

    启动类添加@ServletComponentScan注解,@ServletComponentScan注解所扫描的包路径必须包含该Filter,代码如下:

    SpringBootApplication @ServletComponentScan(basePackages = "com.example.demo.filter") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

    二、@Bean注解方式

    @Slf4j public class MyFilter2 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info(filterConfig.getFilterName() + " init"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { log.info("myFilter2 begin"); try {  log.info("业务方法执行");  chain.doFilter(request, response); } catch (Exception e) {  log.error("error!", e); } log.info("myFilter2 end"); } @Override public void destroy() { } }

    新建配置类WebConfig.java,配置bean,代码如下:

    @Configuration public class WebConfig { @Bean public FilterRegistrationBean testFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(new MyFilter2()); registration.addUrlPatterns("/test"); // registration.setName("myFilter2"); return registration; } }

     

    Processed: 0.017, SQL: 9