阅读 280

Spring Boot 中 Filter 使用

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

简介

过滤器Filter作为Java三大器之一,在Java Web的使用中有很高的地位。所谓过滤器,就是实现了javax.servlet.Filter接口的服务器端程序。

Filter有如下几个用处:

  • 在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
  • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
  • 在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
  • 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

Filter有如下几个方法:

  • void init(FilterConfig filterConfig) 用于完成过滤器的初始化。
  • void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 实现过滤功能,该方法对每个请求增加额外的处理。
  • void destroy() 用于过滤器销毁前,完成某些资源的回收。

通过@WebFilter实现

通过@WebFilter@ServletComponentScan可实现Filter。其中,@WebFilter标注在实现Filter接口的过滤器类,并标注相应参数;@ServletComponentScan标注在SpringBoot启动类,标注后Servlet、Filter(过滤器)、Listener(监听器)可以直接通过@WebServlet@WebFilter@WebListener注解自动注册,无需其他代码!

具体示例代码如下:

TestFilter.java

package com.example.demo.filter;
​
import org.springframework.core.annotation.Order;
​
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;
​
/**
 * @description:
 * @time: 2021/8/3 16:12
 */
@WebFilter(initParams = {@WebInitParam(name="testFilter",value = "/test")})
@Order(1)
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        System.out.println("-----Filter初始化完成-----");
    }
​
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("-----调用服务前执行代码-----");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("-----调用服务后执行代码-----");
    }
​
    @Override
    public void destroy() {
        Filter.super.destroy();
        System.out.println("Filter已销毁");
    }
}
​
复制代码

TestController.java

package com.example.demo.controller;
​
import com.example.demo.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
​
/**
 * @description:
 * @time: 2021/8/3 16:04
 */
@RestController
public class TestController {
​
    @Autowired
    TestService testService;
​
    @RequestMapping(value = "/test",method = RequestMethod.GET)
    public Object test(){
        testService.printTest();
        return "test";
    }
​
}
复制代码

Demo1Application.java

package com.example.demo;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
​
@SpringBootApplication
@ServletComponentScan
public class Demo1Application {
​
    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }
​
}
复制代码

运行结果如下:

image-20210804100659180

通过@Bean实现

此处为了测试@order的效果,使用了两个过滤器测试。

WebConfig.java

package com.example.demo.config;
​
import com.example.demo.filter.FirstFilter;
import com.example.demo.filter.SecondFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
import javax.servlet.Filter;
​
/**
 * @description:
 * @time: 2021/8/4 10:11
 */
@Configuration
public class WebConfig {
​
    @Bean
    public FilterRegistrationBean firstFilterRegistrationBean(){
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
        filterFilterRegistrationBean.addUrlPatterns("/hello");
        // 设置优先级
        filterFilterRegistrationBean.setOrder(1);
        // 绑定过滤器
        FirstFilter filter = new FirstFilter();
        filterFilterRegistrationBean.setFilter(filter);
        return filterFilterRegistrationBean;
    }
​
​
    @Bean
    public FilterRegistrationBean secondFilterRegistrationBean(){
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
        filterFilterRegistrationBean.addUrlPatterns("/hello");
        // 设置优先级
        filterFilterRegistrationBean.setOrder(2);
        // 绑定过滤器
        SecondFilter filter = new SecondFilter();
        filterFilterRegistrationBean.setFilter(filter);
        return filterFilterRegistrationBean;
    }
}
复制代码

FirstFilter.java

package com.example.demo.filter;
​
import javax.servlet.*;
import java.io.IOException;
​
/**
 * @description:
 * @time: 2021/8/4 10:09
 */
public class FirstFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        System.out.println("-----FirstFilter初始化完成-----");
    }
​
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("-----服务前执行代码FirstFilter-----");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("-----服务后执行代码FirstFilter-----");
    }
​
    @Override
    public void destroy() {
        Filter.super.destroy();
        System.out.println("FirstFilter已销毁");
    }
}
复制代码

SecondFilter.java

package com.example.demo.filter;
​
import javax.servlet.*;
import java.io.IOException;
​
/**
 * @description:
 * @time: 2021/8/4 10:30
 */
public class SecondFilter implements Filter{
​
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        System.out.println("-----SecondFilter初始化完成-----");
    }
​
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("-----服务前执行代码SecondFilter-----");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("-----服务后执行代码SecondFilter-----");
    }
​
    @Override
    public void destroy() {
        Filter.super.destroy();
        System.out.println("SecondFilter已销毁");
    }
}
复制代码

执行效果如下:

image-20210804105054857

通过结果可见,filter的初始化服务时在启动Spring Boot项目的时候就已经完成。而当用户访问服务时,执行的顺序按照order的优先级(数字越小越优先)执行。

文章分类
后端
文章标签