一、问题描述

在 Spring Boot 工程中使用过滤器:

// 过滤器
@WebServlet
public class MyFilter implements Filter {

    @Override
    // 在系统启动时就会执行
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init Method start...");
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // doFilter 方法之前的代码在 Serlet 执行之前先执行
        System.out.println("doFilter1 Method start...");

        // 获取 name 值
        String name = servletRequest.getParameter("name");
        System.out.println("name=====" + name);

        if (name != null && name.equals("赌博")) {
            // 直接返回
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);

        // doFilter 方法之后的代码在 Serlet 执行之前先执行
        System.out.println("doFilter1 Method end...");
    }

    @Override
    public void destroy() {
        System.out.println("destory Method start...");
    }
}

提供一个 Servlet:

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       System.out.println("Get Method start--------------");
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Post Method start--------------");
        resp.getWriter().print("<h1>return post method start</h1>");
    }
}

为 Servlet 配置路径,在 App.java 中添加方法:

	@Bean
    public ServletRegistrationBean myServlet() {
        return new ServletRegistrationBean(new MyServlet(), "/dofilter");
    }

运行结果:
在这里插入图片描述
再写一个过滤器 Filter1:

@Order(2)
public class MyFilter1 implements Filter {...

依次传入参数 name=嘉、赌博、名字,在传入 “赌博” 时,访问页面是空白的,控制台输出如下:
在这里插入图片描述
    可以看到,传入“赌博”时,过滤器1 doFilter 没有执行,也就是说,这时并没有进到 Servlet 中,以及 doFilter 之后的方法也没再执行了,所以这里没有打印 “doFilter1 Method end…” ,而 另一个过滤器都执行着呢。
    接下来给刚开始的过滤器(也就是外层那个过滤器)中添加过滤 “赌博” 的逻辑,过滤器1 只是打印字符串,第一次就传入参数 name=赌博,页面自然是空白的,运行结果:
在这里插入图片描述

    可以看到,在最外层就 return 了,不会进入过滤器链。
    以上是 servlet 过滤器的使用演示,接下来发现了一个问题:

    运行程序时,这两个过滤器对所有的 Servlet 都进行了过滤, 于是我用 @WebFilter(urlPatterns = {"/dofilter"}) 注解指定过滤路径,但是并不起作用,这里的问题就是,同时使用 @WebFilter 和 @Component,Spring Boot将会自动注册过滤器,不管写成什么拦截地址,过滤器注册的地址都是 “/*”。 (真的好坑 !😑)

    

二、解决方法

    使用注册 Bean 的方式,在 自己写的过滤类 Myfilter 上使用 @Component 注解,让 Spring 容器能识别到过滤器组件,然后 通过 FilterRegistrationBean 对象的 addUrlPatterns 方法来指定过滤器的过滤地址:

@Configuration
public class Config {

    @Autowired
    Myfilter myfilter;

    @Bean
    public FilterRegistrationBean registrationProjectFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(myfilter);
        registration.addUrlPatterns("/dofilter");
        return registration;
    }
}

    

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐