JavaEE 使用Filter实现敏感词汇过滤器

动态代理实现敏感词汇过滤器

使用动态代理增强request的getParameter(),getParameterMap()和getParameterValues()这三个方法,以达到过滤敏感词汇的效果

##步骤

  1. 创建敏感词汇的txt文件
  2. 创建敏感词汇过滤器的Filter类
  3. 创建测试类进行测试
定义敏感词汇的文件txt

JavaEE 使用Filter实现敏感词汇过滤器_第1张图片

定义敏感词汇过滤器Filter类
import org.apache.commons.beanutils.BeanMap;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
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.*;

/**
 * 敏感词汇过滤器
 */
@SuppressWarnings("all")
@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {
     
    public void destroy() {
     
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
     
        //创建代理对象
        ServletRequest proxy_request = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
     
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     
                //判断是否是getParameter方法,增强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;
                }

                if (method.getName().equals("getParameterMap")) {
     
                    //增强getParameterMap方法
                    //获取参数
                    //定义一个新的map集合
                    Map<String, String[]> newMap = new HashMap<String, String[]>();

                    Map<String, String[]> map = (Map<String, String[]>) method.invoke(req, args);
                    Set<String> keySet = map.keySet();
                    for (String key : keySet) {
     
                        String[] values = map.get(key);
                        //定义一个String数组
                        String[] newValues = new String[values.length];
                        if (values != null) {
     
                            for (int i = 0; i < values.length; i++) {
     
                                //遍历集合
                                for (String s : list) {
     
                                    if (values[i].contains(s)) {
     
                                        values[i] = values[i].replaceAll(s, "***");
                                        newValues[i] = values[i];
                                    } else {
     
                                        newValues[i] = values[i];
                                    }
                                }

                            }
                        }
                        newMap.put(key, newValues);
                    }
                    return newMap;
                }

                
                if (method.getName().equals("getParameterValues")) {
     
                    //获取参数的值
                    String[] values = (String[]) method.invoke(req, args);
                    //定义一个新数组
                    String[] newValues = new String[values.length];
                    //遍历数组
                    if (values != null) {
     
                        for (int i = 0; i < values.length; i++) {
     
                            for (String s : list) {
     
                                if (values[i].contains(s)) {
     
                                    newValues[i] = values[i].replaceAll(s, "***");
                                    break;
                                } else {
     
                                    newValues[i] = values[i];
                                }
                            }
                        }
                        return newValues;
                    }
                }
                return method.invoke(req, args);

            }
        });
        //放行
        chain.doFilter(proxy_request, resp);
    }

    private List<String> list = new ArrayList<String>();

    public void init(FilterConfig config) throws ServletException {
     
        try {
     
            //加载文件
            //获取文件的真实路径
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
            //读取文件
            //创建字符缓冲输入流
            BufferedReader br = new BufferedReader(new FileReader(realPath));
            String line;
            while ((line = br.readLine()) != null) {
     
                //添加文件内容到集合
                list.add(line);
            }

        } catch (Exception e) {
     
            e.printStackTrace();
        }
    }

}

注意事项:

  1. 在使用BufferedReader字符缓冲输入流读取文件时,要注意编码问题
  2. 在放行请求时,调用chain的doFilter方法,要注意把代理对象传进去,而不是真实对象
chain.doFilter(proxy_request, resp);
  1. 一定要注意返回值的类型
    request调用getParameter()方法时,返回的是String
    调用getParameterMap方法时,返回的是Map集合,键是String,值是String类型的数组
    调用getParameterValues()方法时,返回的是一个String类型的数组

######定义测试类TestServlet

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
     
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
        /*String tname = request.getParameter("tname");
        String tmsg = request.getParameter("tmsg");*/
        String[] tnames = request.getParameterValues("tname");
        String[] tmsgs = request.getParameterValues("tmsg");
       /* Map map = request.getParameterMap();
        //遍历map
        Set keySet = map.keySet();
        for (String key : keySet) {
            String[] values = map.get(key);
            System.out.println(key + "---" + values[0]);
        }*/
        System.out.println(tmsgs[0]);
        System.out.println(tnames[0]);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
        this.doPost(request, response);
    }
}
浏览器直接访问测试的Servlet

在这里插入图片描述

控制台的结果

JavaEE 使用Filter实现敏感词汇过滤器_第2张图片

你可能感兴趣的:(JavaEE 使用Filter实现敏感词汇过滤器)