1.封装HttpServletRequestWrapper

关于为何要封装:

  • 原生的HttpServletRequest对象中只能调用一次getInputStream()getReader()
  • 原生getInputStram()getReader()全局只能调用一次(共享这唯一的一次),他是读取请求体中的二进制网络数据,因此只能读取一次

源码解析

可以看到是读取解析request请求中的body部分的二进制流,转化为ServletInputStream类型的输入流


关于源码注释的翻译如下

封装,持久化ServletInputStream

自定义类的继承结构如下

一个通用的持久化封装类

new MyHttpServletRequestWrapper()的时候自动会将二进制流持久化到byte[]数组中,作为一个属性可以被该对象调用

/*** 继承关系:* MyHttpServletRequestWrapper——>HttpServletRequestWrapper——>HttpServletRequest* 利用Filter将原生HttpServletRequest包装为MyHttpServletRequestWrapper* (设计模式:装饰者模式)*/
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {/*** 因为一次请求的request.InputStreaam()只能调用一次。其方法获取的是网络输入流* 所以在这里定义个byte数组,来持久化该网络流*/public byte[] bytes;/*** 构造方法*/public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {super(request);//将一次性的网络IO持久化为byte数组bytes = IOUtils.toByteArray(request.getInputStream());}/*** 匿名抽象类ServletInputStream类* 需要重写InputStream中的read()方法* 需要重写ServletInputStream中的抽象方法isFinished isReady setReadListener*/@Overridepublic ServletInputStream getInputStream() throws IOException {return new ServletInputStream(){private int lastIndexRetrieved = -1;private ReadListener readListener = null;@Overridepublic boolean isFinished() {return (lastIndexRetrieved == bytes.length-1);}@Overridepublic boolean isReady() {// This implementation will never block// We also never need to call the readListener from this method, as this method will never return falsereturn isFinished();}@Overridepublic void setReadListener(ReadListener readListener) {this.readListener = readListener;if (!isFinished()) {try {readListener.onDataAvailable();} catch (IOException e) {readListener.onError(e);}} else {try {readListener.onAllDataRead();} catch (IOException e) {readListener.onError(e);}}}@Overridepublic int read() throws IOException {int i;if (!isFinished()) {i = bytes[lastIndexRetrieved+1];lastIndexRetrieved++;if (isFinished() && (readListener != null)) {try {readListener.onAllDataRead();} catch (IOException ex) {readListener.onError(ex);throw ex;}}return i;} else {return -1;}}};}@Overridepublic BufferedReader getReader() throws IOException {ByteArrayInputStream is = new ByteArrayInputStream(bytes);BufferedReader temp = new BufferedReader(new InputStreamReader(is));return temp;}
}

2.通用的过滤器

唯一可以自定义的地方就是步骤2中的敏感词列表,可以自己从mysql中查出一个list,然后用迭代器或for循环来挨个比对替换

//全局拦截
@WebFilter(urlPatterns = "/*",filterName = "AvoidFilter")
//Order数为最小int,全局最优先执行
@Order(-2147483648)
public class AvoidFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}/***这是第一个Filter拦截器,需要将 ServletRequest request对象传给MyHttpServletRequestWrapper* 然后调用getInputStream (会调用MyHttpServletRequestWrapper中重写的方法:多态性)* 此后网络流中的数据就在MyHttpServletRequestWrapper中持久化为了byte[] bytes*  从第二个Filter开始,其ServletRequest对象就是MyHttpServletRequestWrapper*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//1.多态转化 new MyHttpServletRequestWrapper的同时,输入流被持久化到了bytes中MyHttpServletRequestWrapper myHttpServletRequest = new MyHttpServletRequestWrapper((HttpServletRequest) request);HttpServletResponse httpServletResponse = (HttpServletResponse) response;//2.模拟敏感词过滤byte[] bytes = myHttpServletRequest.bytes;String s     = IOUtils.toString(bytes, "UTF-8");/*** 这里一定要写成这种格式,因为replace()返回的是一个新的值*/s = s.replaceAll("傻逼","**");s = s.replaceAll("nmsl","**");byte[] newBytes = s.getBytes(StandardCharsets.UTF_8);myHttpServletRequest.bytes = newBytes;//3.链路调用chain.doFilter(myHttpServletRequest,httpServletResponse);}@Overridepublic void destroy() {Filter.super.destroy();}
}

3.测试

  @PostMapping("/web")public DtoRes webTest(HttpServletRequest request  ,  HttpServletResponse response ,@RequestBody DtoReq dtoReq) throws IOException {System.out.println(dtoReq);return null;}

postman发送请求:

在controller中@RequestBody所获取的信息:

SpringBoot通用的敏感词拦截相关推荐

  1. SpringBoot使用前缀树实现敏感词的过滤

    记录一下使用SpringBoot中使用前缀树对敏感词的一个过滤. 首先呢在resources目录下建立一个文件用来装敏感词例如我在resources/sensitive-words.txt如下: 敏感 ...

  2. 网站是怎么屏蔽脏话的呢:简单学会SpringBoot项目敏感词、违规词过滤方案

    一个社区最重要的就是交流氛围与审查违规,而这两者都少不了对于敏感词进行过滤的自动维护措施.基于这样的措施,我们才能基本保证用户在使用社区的过程中,不至于被敏感违规词汇包围,才能够正常的进行发布帖子和评 ...

  3. flex java 全局拦截_flex + java 过滤敏感词

    过滤敏感词这个相对比较容易做到,网上也很多方法,看得比较多的一个方法就是:把所有的敏感词写入到一个properties文件中,程序启动时拼成一个正则表达式.这个也只是比较基础的敏感词过滤器,比较强大的 ...

  4. java过滤器敏感字的拦截_【JavaWeb】94:如何屏蔽敏感词?

    今天是刘小爱自学Java的第94天. 感谢你的观看,谢谢你. 话不多说,开始今天的学习: 一.用户评论功能 网络上很多平台都会有敏感词屏蔽,有些词语打出来会被和谐掉. 虽说现在主张言论自由,但我大中华 ...

  5. SpringBoot使用SensitiveWord实现敏感词过滤

    包含默认敏感词过滤和自定义敏感词过滤. 导入依赖 <dependency><groupId>com.github.houbb</groupId><artifa ...

  6. SpringBoot使用前缀树过滤敏感词

    前缀树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利 ...

  7. SpringBoot之敏感词过滤

    1. 功能描述 利用前缀树这种数据结构,设计并开发出敏感词过滤工具. 2. 构建敏感词表 resource/sensitive-words.txt 赌博 嫖娼 吸毒 开票 3. 敏感词过滤器 util ...

  8. 很全的敏感词匹配系统的设计与实践

    作者:vivo互联网服务器团队-Liang Kangwu 一.前言 谛听系统是vivo的内容审核平台,保障了vivo各互联网产品持续健康的发展.谛听支持审核多种内容类型,但日常主要审核的内容是文本,下 ...

  9. spring boot 使用DFA算法实现敏感词过滤

    spring boot 使用DFA算法实现敏感词过滤 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的. DFA算法简介 DFA全称为:Deterministi ...

  10. 敏感词过滤,PHP实现的Trie树

    [转载]敏感词过滤,PHP实现的Trie树 原文地址:http://blog.11034.org/2012-07/trie_in_php.html 项目需求,要做敏感词过滤,对于敏感词本身就是一个CR ...

最新文章

  1. linux cuda 如何编译器,linux – Cuda编译器不使用GCC 4.5
  2. Programming Pearls Essay 01
  3. ML之LiRLasso:基于datasets糖尿病数据集利用LiR和Lasso算法进行(9→1)回归预测(三维图散点图可视化)
  4. jenkins配置小结
  5. php header运用细节
  6. Win下通过 Navica t连接Ubuntu下MySQL数据库
  7. python logger_Python:logging 的巧妙设计!
  8. 20180513 实参 形参 数组
  9. 计算机插本2a院校,广东省专插本2A院校有哪些
  10. PRML 十大经典机器学习算法
  11. ni数据采集卡C语言API接口,NI数据采集卡
  12. mysql describe 作为字段_mysql中的describe语法 以及查看 当前库中所有表和字段信息...
  13. matlab线性规划求解函数:linprog
  14. ubuntu18.04: 安装nanomsg
  15. 在定语从句中which和that用法有什么区别
  16. Word基础(三十八)插入书签
  17. 数字信号处理(自学篇)
  18. 2018.7.18 上半年课程总结 4- 高级英语
  19. VMware View中智能卡和证书身份验证
  20. java for循环 等待_在forEach循环中使用异步/等待

热门文章

  1. 图形学基础|深度缓冲(DepthBuffer)
  2. 创建自签名数字证书PFX格式
  3. 极大似然估计(MLE)、最大后验估计(MAE)
  4. 运动世界校园3.0版本逆向分析破解
  5. 网络安全与渗透测试工具导航
  6. 日常工具搬运——python逐行写入txt文件
  7. Pycharm使用os.system()执行cmd代码出现乱码的问题
  8. 2020软考高级系统分析师,你想知道的全在这
  9. 系统分析师教程电子版资料收集
  10. c语言二级题库pdf,C语言二级考试题库.pdf