使用场景

  1. 需要对项目中的所有输入进行前后空格的过滤
  2. 替换一些特殊字符的输入
  3. 解密一些关键性字段
  4. 注入一些参数在请求方法的时候
  5. 返回参数统一处理,如果后台返回空,统一返回成功信息
  6. 身份证等特殊字符统一做 * 号处理等

code

主要就是用到了 RequestBodyAdviceResponseBodyAdvice 两个接口和一个注解
@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@ControllerAdvicepublic 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;/** * 可以定义空返回的时候返回正确的信息,如成功信息 */@RestControllerAdvicepublic 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 中每个工具的使用,如 rabbitmqmysqlmybatisspringbootspringmvc 可以方便初学者,更方便我自己随时取用,github 地址
https://gitee.com/sanri/example

sanri-tools 工具

推广下我的小工具,很实用的解决项目中的一些麻烦的事情,欢迎来 github 点星,fork
https://gitee.com/sanri/sanri-tools-maven