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

网友投稿 776 2023-01-03

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

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

RequestBodyAdvice对Http请求非法字符过滤

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

要求:spring 4.2+

额外的pom.xml

org.apache.commons

commons-io

1.3.2

com.alibaba

fastjson

1.2.44

代码

package com.niugang.controller;

import java.io.IOException;

import java.io.InputStream;

import java.lang.reflect.Type;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

import org.apache.commons.io.IOUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.MethodParameter;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpInputMessage;

import org.springframework.http.converter.HttpMessageConverter;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;

/**

* RequestBodyAdvice:解释

* 允许在将请求的主体读取和转换成一个对象之前对请求进行自定义,

* 并允许在将其传递到控制器方法作为一个@RequestBody或HttpEntity方法参数之前处理结果对象。

*

* @author niugang

*

*/

@ControllerAdvice(basePackages = "com.niugang")

public class MyRequestBodyAdvice implements RequestBodyAdvice {

private final static Logger logger = LoggerFactory.getLogger(MyRequestBodyAdvice.class);

@Override

public boolean supports(MethodParameter methodParameter, Type targetType,

Class extends HttpMessageConverter>> converterType) {

return true;

}

@Override

public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter,

Type targetType, Class extends HttpMessageConverter>> converterType) {

return body;

}

@Override

public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,

Class extends HttpMessageConverter>> converterType) throws IOException {

try {

return new MyHttpInputMessage(inputMessage);

} catch (Exception e) {

e.printStackTrace();

return inputMessage;

}

}

@Override

public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,

Class extends HttpMessageConverter>> converterType) {

return body;

}

class MyHttpInputMessage implements HttpInputMessage {

private HttpHeaders headers;

private InputStream body;

@SuppressWarnings("unchecked")

public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {

String string = IOUtils.toString(inputMessage.getBody(), "UTF-8");

Map mapJson = (Map) JSON.parseObject(string, Map.class);

Map map = new HashMap();

Set> entrySet = mapJson.entrySet();

for (Entry entry : entrySet) {

String key = entry.getKey();

Object objValue = entry.getValue();

if (objValue instanceof String) {

String value = objValue.toString();

map.put(key, filterDangerString(value));

} else { // 针对结合的处理

@SuppressWarnings("rawtypes")

List parseArray = JSONArray.parseArray(objValue.toString(), HashMap.class);

List> listMap = new ArrayList>();

for (Map innerMap : parseArray) {

Map childrenMap = new HashMap();

Set> elseEntrySet = innerMap.entrySet();

for (Entry en : elseEntrySet) {

String innerKey = en.getKey();

Object innerObj = en.getValue();

if (innerObj instanceof String) {

String value = innerObj.toString();

childrenMap.put(innerKey, filterDangerString(value));

}

}

listMap.add(childrenMap);

}

map.put(key, listMap);

}

}

this.headers = inputMessage.getHeaders();

this.body = IOUtils.toInputStream(JSON.toJSONString(map), "UTF-8");

}

@Override

public InputStream getBody() throws IOException {

return body;

}

@Override

public HttpHeaders getHeaders() {

return headers;

}

}

private String filterDangerString(String value) {

if (value == null) {

return null;

}

value = value.replaceAll("\\|", "");

value = value.replaceAll("&", "");

value = value.replaceAll(";", "");

value = value.replaceAll("@", "");

value = value.replaceAll("'", "");

value = value.replaceAll("\\'", "");

value = value.replaceAll("<", "");

value = value.replaceAll("-", "");

value = value.replaceAll(">", "");

value = value.replaceAll("\\(", "");

value = value.replaceAll("\\)", "");

value = value.replaceAll("\\+", "");

value = value.replaceAll("\r", "");

value = value.replaceAll("\n", "");

value = value.replaceAll("script", "");

value = value.replaceAll("select", "");

value = value.replaceAll("\"", "");

value = value.replaceAll(">", "");

value = value.replaceAll("<", "");

value = value.replaceAll("=", "");

value = value.replaceAll("/", "");

return value;

}

}

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

测试

过滤后的数据

自定义RequestBodyAdvice过滤Json表情符号

/**

* @Author: ZhiHao

* @Date: 2021/6/4 19:03

* @Description: 过滤表情符号, POST-json请求

* @Versions 1.0

**/

@ControllerAdvice

@Slf4j

public class FilterEmojiRequestBodyAdvice implements RequestBodyAdvice {

@Override

public boolean supports(MethodParameter methodParameter, Type targetType, Class extends HttpMessageConverter>> converterType) {

Annotation[] annotations = methodParameter.getParameterAnnotations();

for (Annotation ann : annotations) {

Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);

if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {

return true;

}

}

return false;

}

@Override

public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) throws IOException {

return inputMessage;

}

@Override

public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) {

try {

this.filterEmojiAfterBody(body);

} catch (Exception e) {

log.info("过滤表情异常:{}", e);

}

return body;

}

private void filterEmojiAfterBody(Object body) throws IllegalAccessException {

if (null != body) {

Field[] fields = ReflectUtil.getFields(body.getClass());

for (int i = 0; i < fields.length; i++) {

Field field = fields[i];

if (field.isAnnotationPresent(Valid.class)) {

field.setAccessible(true);

this.filterEmojiAfterBody(field.get(body));

}

if (field.isAnnotationPresent(FilterEmoji.class)) {

field.setAccessible(true);

Object value = field.get(body);

if (value instanceof String) {

String str = filterEmoji(value.toString());

field.set(body, str);

}

}

}

}

}

@Override

public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) {

return body;

}

/**

* 过滤emoji 或者 其他非文字类型的字符

*

* @param source

* @return

*/

public static String filterEmoji(String source) {

if (StringUtils.isEmpty(source)) {

return "";

}

if (!containsEmoji(source)) {

return source;//如果不包含,直接返回

}

StringBuilder buf = new StringBuilder();

int len = source.length();

for (int i = 0; i < len; i++) {

char codePoint = source.charAt(i);

if (isNotEmojiCharacter(codePoint)) {

buf.append(codePoint);

}

}

return buf.toString().trim();

}

/**

* 检测是否有emoji字符

*

* @param source

* @return 一旦含有就抛出

*/

public static boolean containsEmoji(String source) {

if (StringUtils.isBlank(source)) {

return false;

}

int len = source.length();

for (int i = 0; i < len; i++) {

char codePoint = source.charAt(i);

if (!isNotEmojiCharacter(codePoint)) {

//判断到了这里表明,确认有表情字符

return true;

}

}

return false;

}

/**

* 判断是否为非Emoji字符

*

* @param codePoint 比较的单个字符

* @return

*/

public static boolean isNotEmojiCharacter(char codePoint) {

return (codePoint == 0x0) ||

(codePoint == 0x9) ||

(codePoint == 0xA) ||

(codePoint == 0xD) ||

((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||

((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||

((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解析Spring Data JPA的Audit功能之审计数据库变更
下一篇:SpringBoot打印详细启动异常信息
相关文章

 发表评论

暂时没有评论,来抢沙发吧~