Dev_Nick

导航

过滤器

为什么需要过滤器?

在项目开发中,经常会涉及到重复代码的实现;如:判断用户是否登录,只有登录的用户才具有操作权限。

解决这类问题有两种方式:

1、抽取重复代码并封装,在用到的地方手动调用。

2、使用过滤器。

过滤器相关API

|-- interface  Filter                过滤器核心接口
     Void  init(filterConfig);    初始化方法,在服务器启动时候执行
  Void  doFilter(request,response,filterChain);   过滤器拦截的业务处理方法
  Void destroy();               销毁过滤器实例时候调用

|-- interface  FilterConfig   获取初始化参数信息

  String getInitParameter(java.lang.String name) ; //根据名字获取初始化参数

  Enumeration getInitParameterNames() //过去所有初始化参数的名字

|-- interface  FilterChain     过滤器链参数;一个个过滤器形成一个执行链;

  void doFilter(ServletRequest request, ServletResponse response)  ;  执行下一个过滤器或放行

过滤器执行流程

(1)用户访问服务器。

(2)过滤器对servlet请求进行拦截。

(3)先进入过滤器进行过滤处理。

(4)过滤器处理完后,放行;此时请求到达servlet/JSP.

(5)servlet处理。

(6)servlet处理完后,再回到过滤器,最后在由tomcat服务器响应用户;

时序图:

过滤器执行过程测试代码:

 1 public class HelloFilter implements Filter{
 2     
 3     // 创建实例
 4     public HelloFilter(){
 5         System.out.println("1. 创建过滤器实例");
 6     }
 7 
 8     @Override
 9     public void init(FilterConfig filterConfig) throws ServletException {
10         System.out.println("2. 执行过滤器初始化方法");
11         
12         // 获取过滤器在web.xml中配置的初始化参数
13         String encoding = filterConfig.getInitParameter("encoding");
14         System.out.println(encoding);
15         
16         // 获取过滤器在web.xml中配置的初始化参数 的名称
17         Enumeration<String> enums =  filterConfig.getInitParameterNames();
18         while (enums.hasMoreElements()){
19             // 获取所有参数名称:encoding、path
20             String name = enums.nextElement();
21             // 获取名称对应的值
22             String value = filterConfig.getInitParameter(name);
23             System.out.println(name + "\t" + value);
24         }
25     }
26 
27     // 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作
28     @Override
29     public void doFilter(ServletRequest request, ServletResponse response,
30             FilterChain chain) throws IOException, ServletException {
31         System.out.println("3. 执行过滤器业务处理方法");
32         // 放行 (去到Servlet)
33         // 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
34         chain.doFilter(request, response);
35         
36         System.out.println("5. Servlet处理完成,又回到过滤器");
37     }
38 
39     @Override
40     public void destroy() {
41         System.out.println("6. 销毁过滤器实例");
42     }
43 
44 }
View Code

使用过滤器处理编码格式

 1 // 过滤器业务处理方法:处理的公用的业务逻辑操作
 2     @Override
 3     public void doFilter(ServletRequest req, ServletResponse res,
 4             FilterChain chain) throws IOException, ServletException {
 5         
 6         // 转型
 7         final HttpServletRequest request = (HttpServletRequest) req;    
 8         HttpServletResponse response = (HttpServletResponse) res;
 9         
10         // 一、处理公用业务
11         request.setCharacterEncoding("UTF-8");                    // POST提交有效
12         response.setContentType("text/html;charset=UTF-8");
13         
14         /*
15          * 出现GET中文乱码,是因为在request.getParameter方法内部没有进行提交方式判断并处理。
16          * String name = request.getParameter("userName");
17          * 
18          * 解决:对指定接口的某一个方法进行功能扩展,可以使用代理!
19          *      对request对象(目标对象),创建代理对象!
20          */
21         HttpServletRequest proxy =  (HttpServletRequest) Proxy.newProxyInstance(
22                 request.getClass().getClassLoader(),         // 指定当前使用的累加载器
23                 new Class[]{HttpServletRequest.class},         // 对目标对象实现的接口类型
24                 new InvocationHandler() {                    // 事件处理器
25                     @Override
26                     public Object invoke(Object proxy, Method method, Object[] args)
27                             throws Throwable {
28                         // 定义方法返回值
29                         Object returnValue = null;
30                         // 获取方法名
31                         String methodName = method.getName();
32                         // 判断:对getParameter方法进行GET提交中文处理
33                         if ("getParameter".equals(methodName)) {
34                             
35                             // 获取请求数据值【 <input type="text" name="userName">】
36                             String value = request.getParameter(args[0].toString());    // 调用目标对象的方法
37                             
38                             // 获取提交方式
39                             String methodSubmit = request.getMethod(); // 直接调用目标对象的方法
40                             
41                             // 判断如果是GET提交,需要对数据进行处理  (POST提交已经处理过了)
42                             if ("GET".equals(methodSubmit)) {
43                                 if (value != null && !"".equals(value.trim())){
44                                     // 处理GET中文
45                                     value = new String(value.getBytes("ISO8859-1"),"UTF-8");
46                                 }
47                             } 
48                             return value;
49                         }
50                         else {
51                             // 执行request对象的其他方法
52                             returnValue = method.invoke(request, args);
53                         }
54                         
55                         return returnValue;
56                     }
57                 });
58         
59         // 二、放行 (执行下一个过滤器或者servlet)
60         chain.doFilter(proxy, response);        // 传入代理对象
61     }
View Code

使用过滤器处理无效数据

 1 public class DateFilter implements Filter {
 2     
 3     // 初始化无效数据
 4     private List<String> dirtyData;
 5     @Override
 6     public void init(FilterConfig filterConfig) throws ServletException {
 7         // 模拟几个数据
 8         dirtyData = new ArrayList<String>();
 9         dirtyData.add("NND");
10         dirtyData.add("炸使馆");
11     }
12 
13     @Override
14     public void doFilter(ServletRequest req, ServletResponse res,
15             FilterChain chain) throws IOException, ServletException {
16         
17         // 转型
18         final HttpServletRequest request = (HttpServletRequest) req;    
19         HttpServletResponse response = (HttpServletResponse) res;
20         
21         // 一、处理公用业务
22         request.setCharacterEncoding("UTF-8");                    // POST提交有效
23         response.setContentType("text/html;charset=UTF-8");
24         
25         HttpServletRequest proxy =  (HttpServletRequest) Proxy.newProxyInstance(
26                 request.getClass().getClassLoader(),         // 指定当前使用的累加载器
27                 new Class[]{HttpServletRequest.class},         // 对目标对象实现的接口类型
28                 new InvocationHandler() {                    // 事件处理器
29                     @Override
30                     public Object invoke(Object proxy, Method method, Object[] args)
31                             throws Throwable {
32                         // 定义方法返回值
33                         Object returnValue = null;
34                         // 获取方法名
35                         String methodName = method.getName();
36                         // 判断:对getParameter方法进行GET提交中文处理
37                         if ("getParameter".equals(methodName)) {
38                             
39                             // 获取请求数据值【 <input type="text" name="userName">】
40                             String value = request.getParameter(args[0].toString());    // 调用目标对象的方法
41                             
42                             // 获取提交方式
43                             String methodSubmit = request.getMethod(); // 直接调用目标对象的方法
44                             
45                             // 判断如果是GET提交,需要对数据进行处理  (POST提交已经处理过了)
46                             if ("GET".equals(methodSubmit)) {
47                                 if (value != null && !"".equals(value.trim())){
48                                     // 处理GET中文
49                                     value = new String(value.getBytes("ISO8859-1"),"UTF-8");
50                                 }
51                             } 
52                             
53                             // 中文数据已经处理完: 下面进行无效数据过滤   
54                             //【如何value中出现dirtyData中数据,用****替换】  
55                             for (String data : dirtyData) {
56                                 // 判断当前输入数据(value), 是否包含无效数据
57                                 if (value.contains(data)){
58                                     value = value.replace(data, "*****");
59                                 }
60                             }
61                             // 处理完编码、无效数据后的正确数据
62                             return value;
63                         }
64                         else {
65                             // 执行request对象的其他方法
66                             returnValue = method.invoke(request, args);
67                         }
68                         
69                         return returnValue;
70                     }
71                 });
72         
73         // 二、放行 (执行下一个过滤器或者servlet)
74         chain.doFilter(proxy, response);        // 传入代理对象
75     }
76 
77 
78 
79     @Override
80     public void destroy() {
81         
82     }
83 }
View Code

web.xml文件中的配置

 1 <!--1.  编码处理过滤器配置
 2     <filter>
 3         <filter-name>encoding</filter-name>
 4         <filter-class>cn.itcast.a_loginFilter.EncodingFilter</filter-class>
 5     </filter>
 6     <filter-mapping>
 7         <filter-name>encoding</filter-name>
 8         <url-pattern>/*</url-pattern>
 9     </filter-mapping>
10      -->
11      
12      <!-- 2. 无效数据过滤器配置 -->
13      <filter>
14          <filter-name>dataFilter</filter-name>
15          <filter-class>cn.itcast.b_filter_data.DateFilter</filter-class>
16      </filter>
17      <filter-mapping>
18          <filter-name>dataFilter</filter-name>
19          <url-pattern>/*</url-pattern>
20      </filter-mapping>
View Code

 

posted on 2017-05-07 14:29  Dev_Nick  阅读(165)  评论(0编辑  收藏  举报