服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 使用RequestBodyAdvice实现对Http请求非法字符过滤

使用RequestBodyAdvice实现对Http请求非法字符过滤

2021-09-17 10:29盲目的拾荒者 Java教程

这篇文章主要介绍了使用RequestBodyAdvice实现对Http请求非法字符过滤的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

RequestBodyAdvice对Http请求非法字符过滤

利用RequestBodyAdvice对HTTP请求参数放入body中的参数进行非法字符过滤。

要求:spring 4.2+

额外的pom.xml

  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-io</artifactId>
  4. <version>1.3.2</version>
  5. </dependency>
  6.  
  7. <dependency>
  8. <groupId>com.alibaba</groupId>
  9. <artifactId>fastjson</artifactId>
  10. <version>1.2.44</version>
  11. </dependency>

代码

  1. package com.niugang.controller;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.lang.reflect.Type;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Map.Entry;
  10. import java.util.Set;
  11. import org.apache.commons.io.IOUtils;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.core.MethodParameter;
  15. import org.springframework.http.HttpHeaders;
  16. import org.springframework.http.HttpInputMessage;
  17. import org.springframework.http.converter.HttpMessageConverter;
  18. import org.springframework.web.bind.annotation.ControllerAdvice;
  19. import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
  20. import com.alibaba.fastjson.JSON;
  21. import com.alibaba.fastjson.JSONArray;
  22. /**
  23. * RequestBodyAdvice:解释
  24. * 允许在将请求的主体读取和转换成一个对象之前对请求进行自定义,
  25. * 并允许在将其传递到控制器方法作为一个@RequestBody或HttpEntity方法参数之前处理结果对象。
  26. *
  27. * @author niugang
  28. *
  29. */
  30. @ControllerAdvice(basePackages = "com.niugang")
  31. public class MyRequestBodyAdvice implements RequestBodyAdvice {
  32. private final static Logger logger = LoggerFactory.getLogger(MyRequestBodyAdvice.class);
  33.  
  34. @Override
  35. public boolean supports(MethodParameter methodParameter, Type targetType,
  36. Class<? extends HttpMessageConverter<?>> converterType) {
  37. return true;
  38. }
  39.  
  40. @Override
  41. public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
  42. Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
  43. return body;
  44. }
  45.  
  46. @Override
  47. public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
  48. Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
  49.  
  50. try {
  51. return new MyHttpInputMessage(inputMessage);
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. return inputMessage;
  55. }
  56. }
  57. @Override
  58. public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
  59. Class<? extends HttpMessageConverter<?>> converterType) {
  60. return body;
  61. }
  62.  
  63. class MyHttpInputMessage implements HttpInputMessage {
  64. private HttpHeaders headers;
  65. private InputStream body;
  66. @SuppressWarnings("unchecked")
  67. public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
  68. String string = IOUtils.toString(inputMessage.getBody(), "UTF-8");
  69. Map<String, Object> mapJson = (Map<String, Object>) JSON.parseObject(string, Map.class);
  70. Map<String, Object> map = new HashMap<String, Object>();
  71. Set<Entry<String, Object>> entrySet = mapJson.entrySet();
  72. for (Entry<String, Object> entry : entrySet) {
  73. String key = entry.getKey();
  74. Object objValue = entry.getValue();
  75. if (objValue instanceof String) {
  76. String value = objValue.toString();
  77. map.put(key, filterDangerString(value));
  78. } else { // 针对结合的处理
  79. @SuppressWarnings("rawtypes")
  80. List<HashMap> parseArray = JSONArray.parseArray(objValue.toString(), HashMap.class);
  81. List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
  82. for (Map<String, Object> innerMap : parseArray) {
  83. Map<String, Object> childrenMap = new HashMap<String, Object>();
  84. Set<Entry<String, Object>> elseEntrySet = innerMap.entrySet();
  85. for (Entry<String, Object> en : elseEntrySet) {
  86. String innerKey = en.getKey();
  87. Object innerObj = en.getValue();
  88. if (innerObj instanceof String) {
  89. String value = innerObj.toString();
  90. childrenMap.put(innerKey, filterDangerString(value));
  91. }
  92. }
  93. listMap.add(childrenMap);
  94. }
  95. map.put(key, listMap);
  96. }
  97. }
  98. this.headers = inputMessage.getHeaders();
  99. this.body = IOUtils.toInputStream(JSON.toJSONString(map), "UTF-8");
  100. }
  101.  
  102. @Override
  103. public InputStream getBody() throws IOException {
  104. return body;
  105. }
  106.  
  107. @Override
  108. public HttpHeaders getHeaders() {
  109. return headers;
  110. }
  111. }
  112. private String filterDangerString(String value) {
  113. if (value == null) {
  114. return null;
  115. }
  116. value = value.replaceAll("\\|", "");
  117. value = value.replaceAll("&", "");
  118. value = value.replaceAll(";", "");
  119. value = value.replaceAll("@", "");
  120. value = value.replaceAll("'", "");
  121. value = value.replaceAll("\\'", "");
  122. value = value.replaceAll("<", "");
  123. value = value.replaceAll("-", "");
  124. value = value.replaceAll(">", "");
  125. value = value.replaceAll("\\(", "");
  126. value = value.replaceAll("\\)", "");
  127. value = value.replaceAll("\\+", "");
  128. value = value.replaceAll("\r", "");
  129. value = value.replaceAll("\n", "");
  130. value = value.replaceAll("script", "");
  131. value = value.replaceAll("select", "");
  132. value = value.replaceAll("\"", "");
  133. value = value.replaceAll(">", "");
  134. value = value.replaceAll("<", "");
  135. value = value.replaceAll("=", "");
  136. value = value.replaceAll("/", "");
  137. return value;
  138. }
  139. }

对于以上的配置Controller接收参数需要加@RequestBody。

测试

使用RequestBodyAdvice实现对Http请求非法字符过滤

过滤后的数据

使用RequestBodyAdvice实现对Http请求非法字符过滤

自定义RequestBodyAdvice过滤Json表情符号

  1. /**
  2. * @Author: ZhiHao
  3. * @Date: 2021/6/4 19:03
  4. * @Description: 过滤表情符号, POST-json请求
  5. * @Versions 1.0
  6. **/
  7. @ControllerAdvice
  8. @Slf4j
  9. public class FilterEmojiRequestBodyAdvice implements RequestBodyAdvice {
  10. @Override
  11. public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
  12. Annotation[] annotations = methodParameter.getParameterAnnotations();
  13. for (Annotation ann : annotations) {
  14. Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
  15. if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
  16. return true;
  17. }
  18. }
  19. return false;
  20. }
  21. @Override
  22. public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
  23. return inputMessage;
  24. }
  25. @Override
  26. public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
  27. try {
  28. this.filterEmojiAfterBody(body);
  29. } catch (Exception e) {
  30. log.info("过滤表情异常:{}", e);
  31. }
  32. return body;
  33. }
  34. private void filterEmojiAfterBody(Object body) throws IllegalAccessException {
  35. if (null != body) {
  36. Field[] fields = ReflectUtil.getFields(body.getClass());
  37. for (int i = 0; i < fields.length; i++) {
  38. Field field = fields[i];
  39. if (field.isAnnotationPresent(Valid.class)) {
  40. field.setAccessible(true);
  41. this.filterEmojiAfterBody(field.get(body));
  42. }
  43. if (field.isAnnotationPresent(FilterEmoji.class)) {
  44. field.setAccessible(true);
  45. Object value = field.get(body);
  46. if (value instanceof String) {
  47. String str = filterEmoji(value.toString());
  48. field.set(body, str);
  49. }
  50. }
  51. }
  52. }
  53. }
  54. @Override
  55. public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
  56. return body;
  57. }
  58. /**
  59. * 过滤emoji 或者 其他非文字类型的字符
  60. *
  61. * @param source
  62. * @return
  63. */
  64. public static String filterEmoji(String source) {
  65. if (StringUtils.isEmpty(source)) {
  66. return "";
  67. }
  68. if (!containsEmoji(source)) {
  69. return source;//如果不包含,直接返回
  70. }
  71. StringBuilder buf = new StringBuilder();
  72. int len = source.length();
  73. for (int i = 0; i < len; i++) {
  74. char codePoint = source.charAt(i);
  75. if (isNotEmojiCharacter(codePoint)) {
  76. buf.append(codePoint);
  77. }
  78. }
  79. return buf.toString().trim();
  80. }
  81. /**
  82. * 检测是否有emoji字符
  83. *
  84. * @param source
  85. * @return 一旦含有就抛出
  86. */
  87. public static boolean containsEmoji(String source) {
  88. if (StringUtils.isBlank(source)) {
  89. return false;
  90. }
  91. int len = source.length();
  92. for (int i = 0; i < len; i++) {
  93. char codePoint = source.charAt(i);
  94. if (!isNotEmojiCharacter(codePoint)) {
  95. //判断到了这里表明,确认有表情字符
  96. return true;
  97. }
  98. }
  99. return false;
  100. }
  101. /**
  102. * 判断是否为非Emoji字符
  103. *
  104. * @param codePoint 比较的单个字符
  105. * @return
  106. */
  107. public static boolean isNotEmojiCharacter(char codePoint) {
  108. return (codePoint == 0x0) ||
  109. (codePoint == 0x9) ||
  110. (codePoint == 0xA) ||
  111. (codePoint == 0xD) ||
  112. ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
  113. ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
  114. ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
  115. }
  116. }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/niugang0920/article/details/80679096

延伸 · 阅读

精彩推荐
  • Java教程20个非常实用的Java程序代码片段

    20个非常实用的Java程序代码片段

    这篇文章主要为大家分享了20个非常实用的Java程序片段,对java开发项目有所帮助,感兴趣的小伙伴们可以参考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter写文件写不进去或缺失数据的解决

    Java BufferWriter写文件写不进去或缺失数据的解决

    这篇文章主要介绍了Java BufferWriter写文件写不进去或缺失数据的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望...

    spcoder14552021-10-18
  • Java教程升级IDEA后Lombok不能使用的解决方法

    升级IDEA后Lombok不能使用的解决方法

    最近看到提示IDEA提示升级,寻思已经有好久没有升过级了。升级完毕重启之后,突然发现好多错误,本文就来介绍一下如何解决,感兴趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程xml与Java对象的转换详解

    xml与Java对象的转换详解

    这篇文章主要介绍了xml与Java对象的转换详解的相关资料,需要的朋友可以参考下...

    Java教程网2942020-09-17
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    这篇文章主要介绍了Java使用SAX解析xml的示例,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java8中Stream使用的一个注意事项

    Java8中Stream使用的一个注意事项

    最近在工作中发现了对于集合操作转换的神器,java8新特性 stream,但在使用中遇到了一个非常重要的注意点,所以这篇文章主要给大家介绍了关于Java8中S...

    阿杜7472021-02-04
  • Java教程Java实现抢红包功能

    Java实现抢红包功能

    这篇文章主要为大家详细介绍了Java实现抢红包功能,采用多线程模拟多人同时抢红包,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙...

    littleschemer13532021-05-16
  • Java教程小米推送Java代码

    小米推送Java代码

    今天小编就为大家分享一篇关于小米推送Java代码,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...

    富贵稳中求8032021-07-12