Filter:过滤器
步骤:
- 1.定义一个类,实现Filter
- 2.复写方法
- 3.配置拦截路径
web.xml的配置
1 2 3 4 5 6 7 8
| <filter> <filter-name>demo1</filter-name> <filter-class>cn.filter.demo1</filter-class> </filter> <filter-mapping> <filter-name>demo1</filter-name> <url-pattern>/*</url-pattern>//拦截路径 </filter-mapping>
|
过滤器的生命周期
- 1.init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次用于加载资源
- 2.doFilter:每次拦截资源时被执行,执行很多次。
- 3.destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。执行一次,用于释放资源。
拦截路径的配置
- 1.具体的资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 2.目录拦截: /user/* 访问/user下的所有资源时,过滤器都会被执行
- 3.后缀名拦截: *.jsp 访问所有后缀名为jsp的资源时,过滤器都会被执行
- 4.拦截所有资源: /* 访问所有资源时,过滤器都会被执行
拦截方式的配置
注解配置:
1.REQUEST:默认值 浏览器直接请求资源
2.FORWARD:转发访问资源
3.INCLUDE:包含访问资源
4.ERROR:错误跳转
5.ASYNC:异步访问资源
过滤器先后顺序问题
1.注解配置:按照类名的字符串比较规则比较,值小的先执行
2.web.xml配置:<filter-mappping>谁定义在前面,谁先执行
登录案例
判断是否登录
分析
1.判断是否是登录的相关资源
* 是 直接放行
* 不是 判断是否登录
2.判断当前用户是否登录,判断Session是否有user
* 有 已经登录 放行
* 没有 没有登录 跳转到登录页面
代码实现
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 40 41 42 43 44 45 46 47
| package cn.test.web.filter;
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException;
/** * 登录验证的过滤器 */ @WebFilter("/*") public class loginFilter implements Filter { public void destroy() { }
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //0.强制转换 HttpServletRequest request = (HttpServletRequest) req;
//1.获取请求资源的路径 String uri = request.getRequestURI();
//2.判断是否包含登录相关的路径 if (uri.contains("/login.jsp") || uri.contains("/loginServlet") || uri.contains("/checkcodeServlet") || uri.contains("/js/")){ //放行 chain.doFilter(req, resp); }else { //不包含 需要验证用户是否登录 //从Session获取user Object user = request.getSession().getAttribute("user"); if (user!=null){ //登录了 放行 chain.doFilter(req, resp); }else { //没有登录 跳转登录页面 request.setAttribute("login_msg","您尚未登录,请登录"); request.getRequestDispatcher("/login.jsp").forward(request,resp); } }
}
public void init(FilterConfig config) throws ServletException {
}
}
|
敏感词汇过滤
分析
1.对request对象进行增强。增强获取参数相关方法
2.放行。爨地代理对象
增强对象的功能
设计模式:一些通用的解决固定问题的方式
* 1.装饰模式
* 2.代理模式
实现步骤:
- 1.代理对象和真实对象实现相同的接口
- 2.代理对象 = Proxy.newProxyInstance();
- 3.使用代理对象调用方法
- 4.增强方法
增强方式:
- 1.增强参数列表
- 2.增强返回值类型
- 3.增强方法体执行逻辑
代码实现
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| package cn.test.web.filter;
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.BufferedReader; import java.io.FileNotFoundException; 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.*;
/** * 敏感词汇过滤器 */ @WebFilter("/*") public class sensitiveWordsFilter implements Filter { public void destroy() { }
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //创建代理对象,增强getParameter方法 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; } //判断是否是getParameterMap if (method.getName().equals("getParameterMap")){ //由request得到的原数组不可改变,他是被锁住的,所以这里创建一个新数组来复制原数组,返回新的数组 //其实想法很想简单,既然传递进来的映射不可改变,那么自己new一个出来不就行了 Map<String,String[]> map1 = new HashMap<>(); Map<String,String[]> map = (Map<String, String[]>) method.invoke(req,args); Set<String> keySet = map.keySet();
if (keySet != null){ for (String str:list){ for (String key:keySet){ String[] values = map.get(key); for (int i=0;i<values.length;i++){ String value = values[i]; if (value.contains(str)){ value = value.replaceAll(str,"***"); values[i] = value; } }map1.put(key,values); } } } return map1; } return method.invoke(req,args); } });
//放行 chain.doFilter(proxy_req, resp); } private List<String> list = new ArrayList<String>();//敏感词汇 public void init(FilterConfig config) throws ServletException { try { //获取文件真实路径 ServletContext context = config.getServletContext(); String realPath = context.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();//释放资源 System.out.println(list); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
}
|