概念:当访问服务器资源的时候,过滤器可以将请求拦截下来,完成一些特殊的功能;如:登录验证、统一编码处理、敏感字符过滤
步骤:
-
定义一个类,实现接口Filter
-
复写方法
-
配置拦截路径
-
web.xml
<filter> <filter-name>filterDemo</filter-name> <filter-class>filter.FilterDemo</filter-class> </filter> <filter-mapping> <filter-name>filterDemo</filter-name> <url-pattern>/demo</url-pattern> </filter-mapping>
-
注解 @WebFilter(“/*”) //访问所有资源之前,都会执行改过滤器
-
生命周期方法:
- init:在服务器启动后,会创建Filter对象,然后调用init方法,只执行一次。用于加载资源
- doFilter:每一次请求被拦截资源时,会执行。可以执行多次
- dostroy:在服务器关闭后,Filter对象被销毁。如果服务器正常关闭,则会执行destroy方法。只执行一次,用于释放资源
拦截路径常用写法:
- 具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 拦截目录:/user/* 访问/user下的所有资源时,过滤器才会执行
- 后缀名拦截:*.do 访问所有后缀名为.do资源时,过滤器才会执行
- 拦截所有资源:/* 访问所有资源时,过滤器都会拦截
拦截方式配置:
-
注解配置:
-
设置dispatcherTypes属性
-
REQUEST:默认值。浏览器直接请求的资源
-
FORWARD:转发访问资源
-
INCLUDE:包含访问资源
-
ERROR:错误跳转资源
-
ASYNC:异步访问资源
-
@WebFilter(value = "/*",dispatcherTypes = DispatcherType.FORWARD) @WebFilter(value = "/*", dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}) //支持多种方式
-
-
-
web.xml配置
-
<filter> <filter-name>filterDemo</filter-name> <filter-class>filter.FilterDemo</filter-class> </filter> <filter-mapping> <filter-name>filterDemo</filter-name> <url-pattern>/demo</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
-
过滤器链(配置多个过滤器):
- 执行顺序:如果有两个过滤器:过滤器1和过滤器2
- 过滤器1
- 过滤器2
- 资源执行
- 过滤器2
- 过滤器1
过滤器先后顺序:
- 注解配置:按照类名的字符串比较规则比较,值小的先执行
- 如:Afilter和Bfilter,Afilter先执行
- web.xml配置:谁定义在上边,谁先执行
增强对象的方式:
-
装饰模式
-
代理模式:
-
概念:
- 真实对象:被代理的对象
- 代理对象:
- 代理模式:代理对象代理真实对象,达到增强真实对象的目的
-
实现方式:
-
静态代理:有一个类文件描述代理模式
-
动态代理:在内存中形成代理类
- 实现步骤:
- 代理对象和真实对象实现相同的接口
- 代理对象 = Proxy.newProxyInstance()
- 使用代理对象调用方法
- 增强方式:
- 增强参数列表
- 增强返回值类型
- 增强方法体执行逻辑
- 实现步骤:
-
package filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServlet; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; @WebFilter(value = "/*", dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}) //访问所有资源之前,都会执行改过滤器 public class FilterDemo implements Filter { private List<String> list = new ArrayList<String>(); //敏感词汇集合 @Override public void init(FilterConfig filterConfig) throws ServletException { try { //获取文件真实路径 ServletContext servletContext = filterConfig.getServletContext(); String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt"); //读取文件 BufferedReader br = new BufferedReader(new FileReader(realPath)); //将文件的每一行数据添加到list中 String line = null; while ((line = br.readLine()) != null) { list.add(line); } br.close(); } catch (Exception e) { e.printStackTrace(); } } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //1.创建代理对象,增强getParameter方法 HttpServlet req = (HttpServlet) servletRequest; ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //判断是否是getParameter方法 if (method.getName().equals("getParameter")) { //增强返回值 String value = (String) method.invoke(req, args); if(value != null){ for(String str : list){ if(value.contains(str)){ value = value.replaceAll(str,"***"); } } } return value; } return method.invoke(req, args); } }); filterChain.doFilter(proxy_req, servletResponse); } @Override public void destroy() { Filter.super.destroy(); } }
-
-