java.lang.IllegalStateException: 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 类需要满足以下条件

  1. 用final 声明类,使类不可以被继承

  2. 所有的属性字段都用private 修饰,以至于不能直接访问属性

  3. 不提供setter 方法

  4. 使所有的mutable fields 用final 修饰, 以至于这个值只能被分配一次

  5. 用构造函数 深度copy 和初始化所有的字段

  6. 在Getter方法里通过clone 对象,相当于返回一个实际对象的引用。 原文链接:https://blog.csdn.net/gaozhiqiang111/article/details/52440152

而我在拦截了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 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 {
                        //增强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(proxy_req, 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();

            System.out.println(list);

        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public void destroy() {
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值