1.需求:
在日常的生活中大家也知道存在很多侮辱性的词汇,LOL大家很多小伙伴都玩过吧。
经常会看见你**你个**这样字幕,那么是怎么实现的呢,下面我们就完成这样一个类似的功能
1. 对用户存入将要存入数据库的信息进行敏感词汇过滤
2. 把敏感的词汇写在《敏感词汇.txt》
3. 如果是敏感词汇,替换为 ***
2.分析:
1. 对request对象进行增强。增强获取参数相关方法
2. 放行。传递代理对象
3.增强对象的功能:
设计模式:一些通用的解决固定问题的方式
1. 装饰模式
2. 代理模式
概念:
1. 真实对象:被代理的对象
2. 代理对象:
3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
实现方式:
1. 静态代理:有一个类文件描述代理模式
2. 动态代理:在内存中形成代理类
实现步骤:
1. 代理对象和真实对象实现相同的接口
2. 代理对象 = Proxy.newProxyInstance();
3. 使用代理对象调用方法。
4. 增强方法
增强方式:
1. 增强参数列表
2. 增强返回值类型
3. 增强方法体执行逻辑
4.完成相关的功能实现
4.1了解一波代理模式
其实不仅仅代理模式能够完成增强功能的效果装饰模式也可以,这里我们就来理解一波代理模式。先问一个问题大家都买过电脑吧,那大家是在哪里买的?以联想为例,大家每个人都是去联想的总公司才能买到电脑吗,显然并不是。我们通过一些代理商也可以买到电脑
4.2Coding
/**
* 敏感词汇过滤器
*/
@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {
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")) {
//增强getParameterMap方法
//获取参数
Map<String, String[]> map = (Map<String, String[]>) method.invoke(req, args);
//定义一个新的map集合
Map<String, String[]> newMap = new HashMap<String, String[]>();
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)) {
newValues[i] = values[i].replaceAll(s, "***");
break;
} else {
newValues[i] = values[i];
}
}
}
}
newMap.put(key, newValues);
}
return newMap;
}
//判断方法名是否是 getParameterValue
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, "***");
} else {
newValues[i] = values[i];
}
}
}
return newValues;
}
}
return method.invoke(req,args);
}
});
//2.放行
chain.doFilter(proxy_req, resp);
}
private List<String> list = new ArrayList<String>();//敏感词汇集合
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() {
}
}
4.3可能会遇到的报错
java.lang.IllegalStateException: No modifications are allowed to a locked ParameterMap
在java中对象直接进行等于操作的时候会关联原对象 原对象不可以进行修改 那新参数也无法进行修改
刚开始我在获取Map<String, String[]> map = (Map<String, String[]>) method.invoke(req, args);时没有 Map<String, String[]> newMap = new HashMap<String, String[]>();就会报错。大家在写的过程中也可以尝试下
5效果
点击提交查看