思路:客户端请求服务器数据,经过Filter过滤(请求放行,响应拦截),服务器向客户端返回数据时,在Filter中修改掉返回数据中违法的部分。

修改服务器的响应需要自定义一个HttpServletResponse的包装类,继承自HttpServletResponseWrapper即可实现自己的HttpServletResponse的包装类。

大概是这样的:

//package com.ecshop.tools;
import java.io.CharArrayWriter;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class ShieldKeywordResponseWrapper extends HttpServletResponseWrapper{
private CharArrayWriter caw;
private PrintWriter pw;
public ShieldKeywordResponseWrapper(HttpServletResponse response) {
super(response);
// 这个是我们保存返回结果的地方
caw = new CharArrayWriter();
// 这个是包装PrintWriter的,让所有结果通过这个PrintWriter写入到caw中
pw = new PrintWriter(caw);
}
@Override
public PrintWriter getWriter() {
return pw;
}
public String getResult() {
return caw.toString();
}
}

因为违法关键词都包含在响应文本消息中,服务器向请求客户端响应文本消息必须获取HttpServletResponse对象中的PrintWriter文本输出流对象进行输出消息,所以我们的这个封装类覆盖HttpServletResponse的getWriter是很重要的一步,我这个封装类的意思是让服务器响应数据时使用我们修改过的PrintWriter文本输出流,输出的数据并不立刻响应给客户,而是把输出的数据都保留在了CharArrayWriter这个对象中,当控制层执行完毕我们就可以在Filter中进行获取CharArrayWriter对象中的数据进行修改了,修改完毕我们在返回给你客户,就是我们想要的效果了。(而默认HttpServletResponse的PrintWriter对象是由tomcat自己所扩展自PrintWriter的CoyoteWriter对象,CoyoteWriter对象所打印的数据都保留在OutputBuffer对象(也是tomcat自己所扩展自Writer的一个对象)中,我们不方便获取它的文本数据,所以我们修改掉它,当OutputBuffer执行flush就发送消息,或者不执行让servlet结束后自动发送消息)。

以上是我看了一点tomcat源码然后瞎推理,对不对无所谓。。

当我们HttpServletResponse的包装类弄完剩下的就好办了。

//我们看下过滤器中的doFilter函数部分代码就足够了
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse res= (HttpServletResponse) response;
   //我们刚刚做的包装类在这里
ShieldKeywordResponseWrapper skrw= new ShieldKeywordResponseWrapper(res);
chain.doFilter(request, skrw);
//在servlet处理完毕后我们开始做处理
String result = skrw.getResult();
//替换关键词为*
Properties p = new Properties();
p.load(ShieldKeywords.class.getResourceAsStream("/keywords.properties"));
Set<Entry<Object, Object>> se= p.entrySet();
for(Entry<Object, Object> e:se){
result = result.replace(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
}
// 输出最终的结果
PrintWriter out = response.getWriter();
out.write(result);
//以下两句无作用,CharArrayWriter中为空函数,tomcat自己提供的OutputBuffer执行这两句才有作用
out.flush();
out.close();
}

最后看下keywords.properties文件的内容:

违法词1=*
违法词2=*

建议web.xml中过滤器配置时只映射响应文本数据的请求url,因有的请求是要获取一个文件流,服务器HttpServletResponse响应时文本输出流和字节流是冲突的,正常情况下两者只可取一,不然会报错

最新文章

  1. em 和 px相互转换
  2. Xml 序列化
  3. 如何书写高质量的jQuery代码
  4. MarkdownPad Win10 无法预览
  5. 《BI那点儿事》SQL Server 2008体系架构
  6. Base64的编码转换方式
  7. 使用spring cloud实现分布式配置管理
  8. emacs notepad notepad++ 撤销比较
  9. Value Dispose() cannot be called while doing CreateHandle().
  10. 蝇量模式(Flyweight Pattern)
  11. xcode6下使用autolayout+sizeclass实践
  12. HDU2084:数塔(DP)
  13. Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.ClassVisitor
  14. OSI七层模型学习笔记
  15. Linux Shell 命令--tr
  16. .NET知识体系(转载)
  17. pypi pack and upload
  18. 使用PsPing测试Azure虚拟机的连通性
  19. doctrine/annotation 的简单使用
  20. python中Strip()函数的用法

热门文章

  1. 学霸网站之NABCD
  2. Kali linux渗透测试的艺术 思维导图
  3. VC++ MFC橡皮筋技术
  4. jsonp跨域js
  5. 【转】非常适用的Sourceinsight插件,提高效率事半功倍
  6. 整合UMDH结果的一个小工具
  7. 斯坦福大学Andrew Ng教授主讲的《机器学习》公开课观后感[转]
  8. 关于$.ajax中data字段的整理--包括json转换和spring注解
  9. WCF入门教程一[什么是WCF]
  10. MySQLdb