Java过滤器(Filter) 1.什么是过滤器 Servlet中的过滤器Filter实现了javax.servlet.Filter接口的服务器端程序,主要用途是过滤字符编码,做一些业务逻辑判断如是否有权限访问页面等
拦截请求,过滤响应
2.运行原理 当客户端向服务器端发送一个请求时,如果有对应的过滤器进行拦截,过滤器可以改变请求的内容、或者重新设置请求协议的相关信息等,然后再将请求发送给服务器端的Servlet进行处理。当Servlet对客户端做出响应时,过滤器同样可以进行拦截,将响应内容进行修改或者重新设置后,再响应给客户端浏览器。在上述过程中,客户端与服务器端并不需要知道过滤器的存在。
在一个Web应用程序中,可以部署多个过滤器进行拦截,这些过滤器组成了一个过滤器链。过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求在这些过滤器之间传递,直到服务器端的Servlet。具体执行流程如下应用场景 自动登录 统一设置编码格式 访问权限控制 敏感字符过滤等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 @Order(1) @WebFilter(filterName = "firstFilter",urlPatterns = "/*") @Component public class MyFilterTest implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { System.out.println("MyFilterTest 初始化 init(FilterConfig filterConfig)" ); String filterName = filterConfig.getFilterName(); System.out.println("filter-name:" +filterConfig.getFilterName()); System.out.println("初始化参数url的值是:" +filterConfig.getInitParameter("url" )); System.out.println(filterConfig.getServletContext()); Enumeration<String> initParameterNames = filterConfig.getInitParameterNames(); System.out.println(filterName); while (initParameterNames.hasMoreElements()) { String paramName = (String) initParameterNames.nextElement(); System.out.println(paramName); } } @Override public void destroy () { System.out.println("MyFilterTest 销毁" ); } @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("MyFilterTest执行前" ); chain.doFilter(request,response); System.out.println("MyFilterTest执行后" ); } }
注:@ServletComponentScan注解的含义在SpringBootApplication(启动类)上使用@ServletComponentScan注解后,Servlet、Filter(过滤器)、Listener(监听器)可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码!@WebFilter+@ServletComponentScan 注解方式支持对 Filter 匹配指定URL,但是不支持指定 Filter 的执行顺序。
使用方式
排序
指定URL
@Component @Order
1
0
@WebFilter @ServletComponentScan
0
1
JavaConfig
1
1
2.Filter的生命周期 1.构造器方法
2.init 初始化方法
3.doFilter 过滤方法
通过控制对chain.doFilter方法的调用,来决定是否需要目标资源。比如可以在用户权限验证,判断用户是否有访问某些资源的权限,有权限放行,没权限不执行chain.doFilter方法
解决中文乱码的问题
Filter不仅可以通过url-pattern来指定拦截哪些url匹配的资源。而且还可以通过servlet-name来指定拦截哪个指定的servlet(专门为某个servlet服务了,servlet-name对应Servlet的相关配置)
4.destroy 销毁方法
3.Filter的执行流程 在我们的请求到达Servle之间是可以经过多个Filter的,一般来说,建议Filter之间不要有关联,各自处理各自的逻辑即可。这样,我们也无需关心执行顺序问题。 如果一定要确保执行顺序,就要对配置进行修改了,执行顺序如下
在web.xml中,filter执行顺序跟的顺序有关,先声明的先执行 使用注解配置的话,filter的执行顺序跟名称的字母顺序有关,例如AFilter会比BFilter先执行 如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter
@Order(1)//@Order里边的数字越小代表越先被该Filter过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Order(1) @WebFilter(filterName = "firstFilter",urlPatterns = "/*") @Component public class FirstFilter implements Filter { @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("first filter 1" ); System.out.println("before:" + response); chain.doFilter(request, response); System.out.println("after:" + response); System.out.println("first filter 2" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 @Order(2) @WebFilter(filterName = "secondFilter",urlPatterns = "/*") @Component public class SecondFilter implements Filter { @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("second filter 1" ); System.out.println("before:" + response); chain.doFilter(request, response); System.out.println("after:" + response); System.out.println("second filter 2" ); } }
控制台打印
1 2 3 4 5 6 7 8 9 10 first filter 1 before:org.apache.catalina.connector.ResponseFacade@5be0afc second filter 1 before:org.apache.catalina.connector.ResponseFacade@5be0afc 1login session 创建成功... after:org.apache.catalina.connector.ResponseFacade@5be0afc second filter 2 after:org.apache.catalina.connector.ResponseFacade@5be0afc first filter 2
4.FilterConfig类 FilterConfig类 是Filter过滤器的配置文件类
Tomcat每次创建Filter的时候,会同时创建一个FilterConfig类,这里包含了Filter配置文件的配置信息
获取 Filter 的名称 filter-name 的内容
获取在 Filter 中 wen.xml 配置的 init-param 初始化参数
获取 ServletContext 对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Configuration public class FilterConfig { @Bean public FilterRegistrationBean registerMyFilter () { FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>(); bean.setOrder(1 ); bean.setFilter(new MyFilter()); bean.addUrlPatterns("/hello/*" ); return bean; } @Bean public FilterRegistrationBean registerMyAnotherFilter () { FilterRegistrationBean<MyAnotherFilter> bean = new FilterRegistrationBean<>(); bean.setOrder(2 ); bean.setFilter(new MyAnotherFilter()); bean.addUrlPatterns("/*" ); return bean; } }