我们在使用filter不可避免的会用到过滤器,在还未使用springboot的的项目的时候,都是讲过滤器配置在web.xml中。配置的越靠前,filter越先执行。现在很多都是用@WebFilter注解,看到下面注解源码,并没有参数指定顺序。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebFilter {
String description() default "";
String displayName() default "";
WebInitParam[] initParams() default {};
String filterName() default "";
String smallIcon() default "";
String largeIcon() default "";
String[] servletNames() default {};
String[] value() default {};
String[] urlPatterns() default {};
DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};
boolean asyncSupported() default false;
}
我们可以同Order来自指定Filter执行顺序,可以通过三种方式来指定Order的值,Order值越小执行优先级越高。
1、通过FilterRegistrationBean 来设置Order的优先级
@Configuration
public class RequestBodyConfig {
@Bean
public FilterRegistrationBean requestBodyFilterRegistration(){
FilterRegistrationBean registration = new FilterRegistrationBean();
//添加过滤器
registration.setFilter(new RequestBodyFilter());
//设置过滤路径,/*所有路径
registration.addUrlPatterns("/*");
registration.setName("requestBodyFilter");
//设置优先级
registration.setOrder(0);
return registration;
}
public class RequestBodyFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
System.out.println("在requestbodyFilter执行代码");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//防止读流一次之后就没有了,所以将流继续写出去
BodyReaderHttpServletRequestWrapper requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
filterChain.doFilter(requestWrapper, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
/**
* request.getInputStream();
* request.getReader();
* 和request.getParameter("key");
* 保存流
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{
private final byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
String bodyString = StreamUtil.getBodyString(request);
body = bodyString.getBytes(Charset.forName("UTF-8"));
}
@Override
public ServletInputStream getInputStream() throws IOException {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}
}
2、@Order方式设置Order值
@Component
@WebFilter(filterName = "signFilter", urlPatterns = "/*")
@Order(-1)
public class SignFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(SignFilter.class);
/**
* 正常情况是通过配置文件获取
*/
private static final String key = "ABCD";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("在signFilter执行代码");
}
@Override
public void destroy() {
}
}
3、通过实现Orderd接口指定Ordered 值
@Component
@WebFilter(filterName = "signFilter", urlPatterns = "/*")
public class SignFilter2 implements Filter,Ordered {
private static final Logger LOGGER = LoggerFactory.getLogger(SignFilter2.class);
/**
* 正常情况是通过配置文件获取
*/
private static final String key = "ABCD";
private int order=-2;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("在signFilter2执行代码");
}
@Override
public void destroy() {
}
@Override
public int getOrder() {
return this.order;
}
}
查看执行结果,通过测试动态无论调整那个,那个filter里面的值,都能使过滤器里面的顺序生效
在signFilter2执行代码
在signFilter执行代码
在requestbodyFilter执行代码