Notice: 函数 WP_Scripts::localize 的调用方法不正确$l10n 参数必须是一个数组。若要将任意数据传递给脚本,请改用 wp_add_inline_script() 函数。 请查阅调试 WordPress来获取更多信息。 (这个消息是在 5.7.0 版本添加的。) in /data/www/appblog/wp-includes/functions.php on line 6131

No modifications are allowed to a locked ParameterMap 解决方案

使用Filter过滤器完成对敏感词汇的过滤,在判断方法名是getParameterMap时出现如下如下报错的问题:

java.lang.IllegalStateException: No modifications are allowed to a locked ParameterMap

结果查了一下发现这是由于javax.servlet.ServletRequest getParameterMap method 返回的是一个不可变(immutable)的对象,

什么是Immutable class?

创建一个Immutable 类需要满足以下条件:

  • 用final 声明类,使类不可以被继承
  • 所有的属性字段都用private 修饰,以至于不能直接访问属性
  • 不提供setter 方法
  • 使所有的mutable fields 用final 修饰,以至于这个值只能被分配一次
  • 用构造函数 深度copy 和初始化所有的字段
  • 在Getter方法里通过clone 对象,相当于返回一个实际对象的引用

而在拦截了getParameterMap的数据后,由于要将含敏感词汇的单词变为***,因此是使用map.put来进行改变的,这就违反了第四条原则,该值只能被分配一次,而解决办法便是在对应的Filter方法中创建一个新的map,将拦截的map赋值给这个新的map,再返回这个被赋值的map即可

代码如下(其中包含了拦截getParameter方法)

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

    private List<String> list = new ArrayList<String>(); //敏感词汇集合

    private Map<String, String[]> map; //创建一个map,用于返回

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //1.创建代理对象,增强getParameter方法

        ServletRequest proxyReq = (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;
                    }
                    //判断方法名是否是 getParameterMap
                    if (method.getName().equals("getParameterMap")) {
                        Map<String, String[]> maps = (Map<String, String[]>) method.invoke(req, args);
                        map = maps;
                        Set set = map.keySet();
                        Iterator it = set.iterator();
                        while (it.hasNext()) {
                            String xh = (String) it.next();
                            String[] value = map.get(xh);
                            for (String str:list) {
                                if (value[0].contains(str)) {
                                    value[0] = value[0].replaceAll(str, "***");
                                }
                            }
                        }
                        return map;
                    }
                    return method.invoke(req, args);
                }
                });
            //2.放行
            chain.doFilter(proxyReq, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        try{
            //1.获取文件真实路径
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
            //2.读取文件
            BufferedReader br = new BufferedReader(new FileReader(realPath));
            //3.将文件的每一行数据添加到list中
            String line = null;
            while ((line = br.readLine())!=null) {
                list.add(line);
            }

            br.close();
            log.info(list);

        } catch (Exception e) {
            log.info("", e);
        }
    }

    public void destroy() {
    }
}
上一篇 Spring Boot向Filter过滤器中的Request对象添加额外的参数
下一篇 SpringBoot设置Filter过滤请求参数