在项目中使用filters可以进行访问权限验证、过滤有XSS威胁的字符、记录访问日志等等。Spring Boot默认在项目中添加了两个Filter:OrderedCharacterEncodingFilter和HiddenHttpMethodFilter。并且也可以自定义Filter。
自定义Servlet Filters现在有两种方法。
老方法自定义Filter步骤:
- 自定义一个类,并实现javax.servlet.Filter接口
- 通过FilterRegistrationBean类把自定义Filter添加到Servlet 3.0+容器中
代码:
package com.example.demo.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfiguration
{
@Bean
public FilterRegistrationBean<TestFilter> testFilterRegistration()
{
// 通过FilterRegistrationBean类把自定义Filter添加到Servlet 3.0+容器中
FilterRegistrationBean<TestFilter> registration = new FilterRegistrationBean<TestFilter>();
registration.setFilter(new TestFilter()); // 设置自定义Filter
registration.addUrlPatterns("/*"); // 设置匹配规则
registration.addInitParameter("paramName", "paramValue"); // 在这里给自定义Filter传递初始化参数
registration.setName("TestFilter"); // 设置注册名称,如果不设置此项,则默认以自定义Filter类的名称做为注册名称
registration.setOrder(1); // 设置过滤优先级,值越小,越先执行
return registration;
}
// 自定义Filter
public class TestFilter implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
// TODO Auto-generated method stub
Filter.super.init(filterConfig);
// 在这里可以获取到FilterRegistrationBean里addInitParameter里设置的参数
System.out.println(filterConfig.getInitParameter("paramName"));
}
@Override
public void doFilter(ServletRequest sRequest, ServletResponse sResponse, FilterChain fChain) throws IOException, ServletException
{
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) sRequest;
// 获取并打印出过滤到的RequestURI
System.out.println("TestFilter URL:" + request.getRequestURI());
// 最后要把请求加入到过滤链中
fChain.doFilter(sRequest, sResponse);
}
}
}
启动Spring Boot项目,会看到控制台打印日志中显示:
Mapping filter: 'TestFilter' to urls: [/*]
paramValue
在浏览器中输入http://localhost:8080/hello,可以看到控制台打印出来过滤到的访问信息:
新方法自定义Filter步骤:
1、自定义一个类,并实现javax.servlet.Filter接口
package com.example.demo.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import org.springframework.core.annotation.Order;
@Order(1) // 设置过滤优先级,值越小,越先执行(目前测试这个功能无效)
@WebFilter(filterName="testFilterNew", urlPatterns= {"/*"}, initParams={@WebInitParam(name="paramNameNew", value="paramValueNew")}) // 设置注册名称、匹配规则、初始化参数
public class TestFilterNew implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
// TODO Auto-generated method stub
Filter.super.init(filterConfig);
System.out.println(filterConfig.getInitParameter("paramNameNew"));
}
@Override
public void doFilter(ServletRequest sRequest, ServletResponse sResponse, FilterChain fChain) throws IOException, ServletException
{
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) sRequest;
// 获取并打印出过滤到的RequestURI
System.out.println("TestFilterNew URL:" + request.getRequestURI());
// 最后要把请求加入到过滤链中
fChain.doFilter(sRequest, sResponse);
}
}
2、在Spring Boot启动类中加入@ServletComponentScan
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan // 扫描Servlet组件
public class DemoApplication
{
public static void main(String[] args)
{
SpringApplication.run(DemoApplication.class, args);
}
}
在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
3、启动Spring Boot项目,会看到控制台打印日志中显示:
Mapping filter: 'testFilterNew' to urls: [/*]
paramValueNew
4、在浏览器中输入http://localhost:8080/hello,可以看到控制台打印出来过滤到的访问信息:
补充:
对于@Order无效的问题
- 通过FilterRegistrationBean的setOrder方法可以实现顺序。
- 经过测试发现,自定义Filter类的class类名的字典正序就是@Order注解加载后的实际执行顺序