利用RequestBodyAdvice对HTTP请求参数放入body中的参数进行非法字符过滤。
- 要求:spring 4.2+
额外的pom.xml
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.44</version> </dependency>
- 代码
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<String, Object> mapJson = (Map<String, Object>) JSON.parseObject(string, Map.class); Map<String, Object> map = new HashMap<String, Object>(); Set<Entry<String, Object>> entrySet = mapJson.entrySet(); for (Entry<String, Object> 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<HashMap> parseArray = JSONArray.parseArray(objValue.toString(), HashMap.class); List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>(); for (Map<String, Object> innerMap : parseArray) { Map<String, Object> childrenMap = new HashMap<String, Object>(); Set<Entry<String, Object>> elseEntrySet = innerMap.entrySet(); for (Entry<String, Object> 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(" ", ""); value = value.replaceAll(" ", ""); 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。
测试
过滤后的数据
微信公众号