You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

!Pasted image 20231120112555.png

一、Filter和Interceptor区别

  1. 来源不同过滤器是javaEE规范拦截器是SpringMVC规范
  2. 执行顺序不同:过滤器(Filter)是在请求进入Tomcat容器之后请求进入Servlet之前执行。Filter是Servlet规范规定的只能用于web程序中。拦截器(Interceptor)是在Servlet和Controller控制器之间执行。
  3. Interceptor是基于java的反射机制的而Filter是基于函数回调。
  4. Interceptor不依赖与servlet容器Filter依赖于servlet容器。
  5. Interceptor只能对action请求起作用而Filter则可以对几乎所有的请求起作用。
  6. Interceptor可以访问action上下文、值栈里的对象而Filter不能访问。
  7. Interceptor以获取IOC容器中的各个bean而过滤器就不行这点很重要在拦截器里注入一个service可以调用业务逻辑。拦截器可以获取ioc中的service bean实现业务逻辑

1.1 过滤器适用场景

  • 过滤敏感词汇防止sql注入
  • 设置字符编码
  • URL级别的权限访问控制
  • 压缩响应信息

1.2 拦截器使用场景

  • 登录验证,判断用户是否登录。
  • 权限验证判断用户是否有权限访问资源如校验token
  • 日志记录记录请求操作日志用户ip访问时间等以便统计请求访问量。
  • 处理cookie、本地化、国际化、主题等。
  • 性能监控,监控请求处理时长等。
  • 通用行为读取cookie得到用户信息并将用户对象放入请求从而方便后续流程使用还有如提取Locale、Theme信息等只要是多个处理器都需要的即可使用拦截器实现

二、Filter 过滤器

过滤器的定义方式:

2.1 使用spring boot提供的FilterRegistrationBean注册Filter

  • 定义Filter
package com.corwien.filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
    @Override public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // do something 处理request 或response
     // doFilter()方法中的servletRequest参数的类型是ServletRequest需要转换为HttpServletRequest类型方便调用某些方法
      System.out.println("filter1"); // 调用filter链中的下一个filter

   HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String ip = request.getRemoteAddr();
        String url = request.getRequestURL().toString();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = new Date();
        String date = sdf.format(d);

        System.out.printf("%s %s 访问了 %s%n", date, ip, url);

        filterChain.doFilter(request, response);
    }
    @Override public void destroy() {

    }
}
  • 注册Filter
@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean registrationBean() {
       ** FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new** **MyFilter());**
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}

2.2 使用原生servlet注解定义Filter

// 注入spring容器
@Component // 定义filterName 和过滤的url
@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*") public class My2Filter 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("filter2");
    }
    @Override public void destroy() {

    }
}

这里直接用@WebFilter就可以进行配置,同样,可以设置url匹配模式过滤器名称等。这里需要注意一点的是@WebFilter这个注解是Servlet3.0的规范并不是Spring boot提供的。除了这个注解以外,我们还需在启动类中加另外一个注解:@ServletComponetScan指定扫描的包。

三、Interceptor 拦截器

实现拦截器可以通过继承 HandlerInterceptorAdapter类也可以通过实现HandlerInterceptor这个接口。 自定义拦截器

public class LogCostInterceptor implements HandlerInterceptor { long start = System.currentTimeMillis();
    @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        start = System.currentTimeMillis(); return true;
    }

    @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
    }

    @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

配置拦截器

@Configuration public class InterceptorConfig extends WebMvcConfigurerAdapter {

    @Override public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**"); super.addInterceptors(registry);
    }
}