动态代理实现敏感词汇过滤器
使用动态代理增强request的getParameter(),getParameterMap()和getParameterValues()这三个方法,以达到过滤敏感词汇的效果
##步骤
- 创建敏感词汇的txt文件
- 创建敏感词汇过滤器的Filter类
- 创建测试类进行测试
定义敏感词汇的文件txt
定义敏感词汇过滤器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() {@Overridepublic 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();}}}
注意事项:
- 在使用BufferedReader字符缓冲输入流读取文件时,要注意编码问题
- 在放行请求时,调用chain的doFilter方法,要注意把代理对象传进去,而不是真实对象
chain.doFilter(proxy_request, resp);
- 一定要注意返回值的类型
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<String, String[]> map = request.getParameterMap();//遍历mapSet<String> 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);}
}