动态代理学习心得_使用动态代理替换请求参数中的敏感字符

@WebFilter("/*")
public class SensitiveFilter implements Filter {
    // 1.创建一个集合装敏感词汇中的数据
    private List<String> list = new ArrayList<>();

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //获取所有的请求参数,如果有敏感词汇则换
        // 创建代理对象
        /**
         * req.getClass().getClassLoader() 真实对象的类加载器
         * req.getClass().getInterfaces() 真实对象所实现的所有的接口们
         *  InvocationHandler 实现代理
         */
        ServletRequest proxy = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            /**
             *
             * @param proxy 代理对象
             * @param method 代理对象执行那个方法,描述的就是哪个方法
             * @param args 代理对象执行的方法的参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 需要进行敏感词汇过滤的方法进行增强
                // 3.判断调用的方法是不是getParameter方法,如果是的话,进行增强
                if (method.getName().equals("getParameter")) {
                    String value = (String) method.invoke(req, args);
                    // 判断,如果value不为空的时候,看是否包含敏感字符
                    // s为敏感字符 ,str为替换后的*
                    if (value != null) {
                       /* for (String s : list) {
                            // 判断,如果包含,则替换
                            if (value.contains(s)) {
                                String str = "";
                                // 判断敏感字符的长度。
                                for (int i = 0; i < s.length(); i++) {
                                    str += "*";
                                }
                                value = value.replaceAll(s, str);
                            }
                        }*/
                       value = replaceAllSensitive(value);
                    }
                    return value;
                }
                // 3.判断调用的方法是不是getParameterMap方法,如果是的话,判断客户传过来的参数部位空的情况下,是否包含敏感字符,如果包含则进行替换、
                if (method.getName().equals("getParameterMap")) {
                    // 调用真实对象调用方法,知道方法返回的是一个map的集合,强转为Map<String, String[]> map集合
                    Map<String, String[]> map = (Map<String, String[]>) method.invoke(req, args);
                    // 判断当map不为空,则对map中的参数进行判断,如果包含敏感字符,则进行替换
                    if (map != null) {
                        // 遍历获取到的每一对参数键值对
                        for (Map.Entry<String, String[]> entry : map.entrySet()) {
                            // 获取到每一个请求参数的值
                            String[] values = entry.getValue();
                            // 遍历所有敏感字符,看参数中是否包含,如果包含,则进行替换
                           /* for (String s : list) {
                                // 判断是否包含铭感字符s、如果包含则换位str “*”;
                                if (values[0].contains(s)) {
                                    // 定义一个空字符串。用来根据敏感字符的字符大小个数对*进行拼接
                                    String str = "";
                                    // 判断字符的个数
                                    for (int i = 0; i < s.length(); i++) {
                                        str += "*";
                                    }
                                    values[0] = values[0].replaceAll(s, str);
                                }
                            }*/
                             replaceAllSensitive(values);
                        }
                    }
                    // 如果满足,则把替换后的map集合返回;
                    return map;
                }

                // 判断方法的名字是否为 如果是的话,获取他的value。然后进行判断是否包含敏感字符
                if (method.getName().equals("getParameterValues")) {
                    // 获取values
                    String[] values = (String[]) method.invoke(req, args);
                    // 进行判断value 。
                    if (values[0] != null) {
                       /* // 遍历敏感字符
                        for (String s : list) {
                            // 判断,如果包含,则替换
                            if (values[0].contains(s)) {
                                String str = "";
                                // 判断敏感字符的长度。
                                for (int i = 0; i < s.length(); i++) {
                                    str += "*";
                                }
                                // 敏感字符替换
                                values[0] = values[0].replaceAll(s, str);
                            }
                        }*/
                         replaceAllSensitive(values);
                    }
                    // 返回values数组进行替换
                    return values;
                }
                // 如果不满足上面的条件,正常的调用方法,正常的返回。
                return method.invoke(req, args);
            }
        });
        // 放行的时候,必须适应动态代理对象调用方法,内部则是使用真实代理调用方法,动态代理进行改造
        chain.doFilter(proxy, resp);
    }

    public void destroy() {
    }

    /**
     * 2.将配置文件加载进内存
     *
     * @param config
     * @throws ServletException
     */
    public void init(FilterConfig config) throws ServletException {

        try {
            ServletContext servletContext = config.getServletContext();
            // 根据servletContext对象,获取配置文件的真实路径
            String realPath = servletContext.getRealPath("/a.txt");
            BufferedReader br = new BufferedReader(new FileReader(realPath));
            String line;
            while ((line = br.readLine()) != null) {
                // 把配置文件中的所有敏感字符都添加到集合中
                list.add(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    // 传入一个字符串,将字符串中的敏感字符进行替换
    public void replaceAllSensitive(String value[]) {
        for (String s : list) {
            // 判断,如果包含,则替换
            if (value[0].contains(s)) {
                String str = "";
                // 判断敏感字符的长度。
                for (int i = 0; i < s.length(); i++) {
                    str += "*";
                }
                value[0] = value[0].replaceAll(s, str);
            }
        }
    }

    // 传入一个字符串,将字符串中的敏感字符进行替换
    public String replaceAllSensitive(String value) {
        for (String s : list) {
            // 判断,如果包含,则替换
            if (value.contains(s)) {
                String str = "";
                // 判断敏感字符的长度。
                for (int i = 0; i < s.length(); i++) {
                    str += "*";
                }
                value = value.replaceAll(s, str);
            }
        }
        return value;
    }
}

测试代码:


@WebServlet("/servletTest")
public class ServletTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String msg = request.getParameter("msg");
        System.out.println(name+":"+msg);

        Map<String, String[]> map = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : map.entrySet()) {
            for (String s : entry.getValue()) {
                System.out.println(entry.getKey() +":"+ s);
            }
        }

        String[] parameterValues = request.getParameterValues("name");
        String[] parameterValues2 = request.getParameterValues("msg");
        for (String value : parameterValues) {
            System.out.println(value);
        }
        for (String value : parameterValues2) {
            System.out.println(value);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

在这里插入图片描述

代理模式的实现方式?
动态代理一个真实对象的实现步骤?
Proxy.newProxyInstance(ClassLoader loader,
							  Class<?>[] interfaces,
							  InvocationHandler h);
	3个参数分别是什么意思?
		ClassLoader loader:类加载器-固定写法:真实对象.getClass().getClassLoader();
		Class<?>[] interfaces:真实对象实现的接口数组-固定书写:真实对象.getClass().getInterfaces();
		InvocationHandler h:处理器-固定书写:new InvocationHandler(){public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			
		}}
		
--------------------------------------------------
当使用代理对象调用任何方法时,InvocationHandler中的invoke方法都会执行!!

--------------------------------------------------

	
InvocationHandler的抽象方法:
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			
		}
	3个参数分别是什么意思?
	proxy:代理对象(不用)
	method:使用代理对象调用的是哪个方法,那么method的描述的就是哪个方法;
	args:使用代理对象调用方法时传递的参数;

学习中遇到的问题:
问题1:动态代理判断方法是否为getParameterMap 时,为什么不能遍历String[]进行设置里面的每一个值
回答:因为request真代理的getParameterMap 方法,返回的是String[] 他所对应的是checkbox复选框。
问题2,共性抽取方法,参数为数组的可以使用,参数为字符串的无法使用
之前的方法中只是在方法中执行了替换的动作,并没有真正的将结果返回。所以需要给方法添加返回值然后接收。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值