RequestBodyAdvice 和 ResponseBodyAdvice 全局处理输入输出
使用场景
- 需要对项目中的所有输入进行前后空格的过滤
- 替换一些特殊字符的输入
- 解密一些关键性字段
- 注入一些参数在请求方法的时候
- 返回参数统一处理,如果后台返回空,统一返回成功信息
- 身份证等特殊字符统一做 * 号处理等
code
主要就是用到了 RequestBodyAdvice
和 ResponseBodyAdvice
两个接口和一个注解 @ControllerAdvice
- 请求参数去空格
package com.sanri.test.testmvc.config; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; import java.util.Iterator; import java.util.Map; /** * 去掉前后空格和特殊字符 */ @Slf4j @ControllerAdvice public class CustomRequestBodyAdvice implements RequestBodyAdvice { @Override public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) { return true; } @Override public Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) { return body; } @Override public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException { return new CustomHttpInputMessage(httpInputMessage); } @Override public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) { return body; } class CustomHttpInputMessage implements HttpInputMessage{ private HttpInputMessage origin; public CustomHttpInputMessage(HttpInputMessage httpInputMessage) { this.origin = httpInputMessage; } @Override public InputStream getBody() throws IOException { HttpHeaders headers = origin.getHeaders(); InputStream body = origin.getBody(); // 空参,get 请求,流为空,非 application/json 请求,不处理参数 MediaType contentType = headers.getContentType(); if(contentType == null){return body;} if(!contentType.isCompatibleWith(MediaType.APPLICATION_JSON)){return body;} if(body == null){return body;} String params = IOUtils.toString(body, "utf-8"); if(StringUtils.isBlank(params)){return body;} // 正式过滤 json 参数 Object parse = JSON.parse(params); if (parse instanceof JSONArray) { JSONArray jsonArray = (JSONArray) parse; trimJsonArray(jsonArray); } else if (parse instanceof JSONObject) { trimJsonObject((JSONObject) parse); } else { log.error("参数不支持去空格:" + parse+ " contentType:"+contentType); } return IOUtils.toInputStream(JSON.toJSONString(parse, SerializerFeature.WriteMapNullValue), "UTF-8"); } private void trimJsonObject(JSONObject jsonObject) { Iterator<Map.Entry<String, Object>> iterator = jsonObject.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Object> next = iterator.next(); String key = next.getKey(); Object value = next.getValue(); if (value instanceof JSONArray) { trimJsonArray((JSONArray) value); }else if(value instanceof JSONObject){ trimJsonObject((JSONObject) value); }else if(value instanceof String){ String trimValue = StringUtils.trim(ObjectUtils.toString(value)); next.setValue(filterDangerString(trimValue)); } } } private void trimJsonArray(JSONArray jsonArray) { for (int i = 0; i < jsonArray.size(); i++) { Object object = jsonArray.get(i); if(object instanceof JSONObject){ JSONObject jsonObject = jsonArray.getJSONObject(i); trimJsonObject(jsonObject); }else if(object instanceof String){ String trimValue = StringUtils.trim(ObjectUtils.toString(object)); jsonArray.set(i,trimValue); } } } @Override public HttpHeaders getHeaders() { return origin.getHeaders(); } private String filterDangerString(String value) { if(StringUtils.isBlank(value))return value; value = value.replaceAll(";", ";"); value = value.replaceAll("'", "‘"); value = value.replaceAll("<", "《"); value = value.replaceAll(">", "》"); value = value.replaceAll("\\(", "("); value = value.replaceAll("\\)", ")"); value = value.replaceAll("\\?", "?"); return value; } } }
- 使用 ResponseBodyAdvice 处理返回空返回
package com.sanri.test.testmvc.config; import com.alibaba.fastjson.JSONObject; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import java.lang.reflect.AnnotatedType; import java.lang.reflect.Executable; import java.lang.reflect.Type; /** * 可以定义空返回的时候返回正确的信息,如成功信息 */ @RestControllerAdvice public class CustomResponseBodyAdvice implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { Executable executable = returnType.getExecutable(); AnnotatedType annotatedReturnType = executable.getAnnotatedReturnType(); Type type = annotatedReturnType.getType(); return JSONObject.parseObject("{\"result\":0}"); } }
项目代码
我弄了一个例子代码,关于 java 中每个工具的使用,如 rabbitmq
,mysql
,mybatis
,springboot
,springmvc
可以方便初学者,更方便我自己随时取用,github 地址
https://gitee.com/sanri/example
sanri-tools 工具
推广下我的小工具,很实用的解决项目中的一些麻烦的事情,欢迎来 github 点星,fork
https://gitee.com/sanri/sanri-tools-maven
相关推荐
88483063 2020-06-28
80337960 2020-06-10
88483063 2020-05-25
88103756 2020-05-02
88483063 2020-04-23
ITprivate 2020-03-26
80337960 2020-03-26
80337960 2020-02-22
88483063 2020-01-29
83163452 2020-01-28
baijinswpu 2020-01-25
88483063 2020-01-11
86403969 2020-01-04
88103756 2020-01-01
88103756 2019-12-24
fengchao000 2019-12-24
80337960 2019-12-23
xufankang 2019-12-19
88483063 2019-12-16