Java动态代理的坑- 类型转换异常- ClassCastException

根据文档,动态代理时传递的第二个参数是一个代理类要实现的接口列表.如果传递的对象不是接口的直接实现类,那么就会报错,可以手动指定.
newProxyInstance
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
Proxy.getProxyClass(loader, interfaces).
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
Proxy.newProxyInstance 抛出 IllegalArgumentException,原因与 Proxy.getProxyClass 相同。

参数:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
返回:
一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口

WebFilter("/*")  /*如果是默认指那么    DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST}: 指的是request 这时候req实现的接口和request一致所以不会报错但是如果是forward,那么
 	*/
public class SensitiveWordFilter implements Filter {

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

    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //过滤请求

        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 {
                if (method.getName().equals("getParameter")) {
                    String str = (String) method.invoke(req, args);
                    if (str != null) {
                        for (String s : list) {
                            if (str.contains(s)) {
                                str = str.replace(s, "***");
                            }
                        }
                    }
                    return str;
                } else if (method.getName().equals("getParameterMap")) {
                    Map<String, String[]> map = (Map<String, String[]>) method.invoke(req, args);
                    for (String str : map.keySet()) {
                        // System.out.println("str"+str);
                        //System.out.println("value"+map.get(str)[0]);
                        for (String s : list) {
                            // System.out.println(s);
                            if (map.get(str)[0].contains(s)) {
                                //  System.out.println(s.equals(map.get(str)[0]));
                                map.get(str)[0] = map.get(str)[0].replace(s, "***");
                                // System.out.println( map.get(str)[0]);
                            }
                        }
                        return map;
                    }
                } else if (method.getName().equals("getParameterValues")) {
                    String[] arrays = (String[]) method.invoke(req, args);
                    if (arrays != null) {
                        for (String str : arrays) {
                            for (String s : list) {
                                if (str.contains(s)) {
                                    str = str.replace(s, "***");
                                }
                            }
                        }
                    }
                    return arrays;
                }
                return method.invoke(req, args);
            }
        });
        //放行
        chain.doFilter(Proxy_req, resp);

如果是forward那么req就是ApplicationHttpRequest此时的接口数组那就就是0,需要手动指定HttpServletRequestWrapper或者接口作为对象调用getInterfaces(),获取接口数组

猜你喜欢

转载自blog.csdn.net/sulaymanyf/article/details/82906566
今日推荐