RequestBodyAdvice 和 ResponseBodyAdvice 全局处理输入输出

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sanri1993/article/details/100168530
使用场景
需要对项目中的所有输入进行前后空格的过滤
替换一些特殊字符的输入
解密一些关键性字段
注入一些参数在请求方法的时候
返回参数统一处理,如果后台返回空,统一返回成功信息
身份证等特殊字符统一做 * 号处理等
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;
        }

    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
使用 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}");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
项目代码
我弄了一个例子代码,关于 java 中每个工具的使用,如 rabbitmq,mysql,mybatis,springboot,springmvc 可以方便初学者,更方便我自己随时取用,github 地址
https://gitee.com/sanri/example

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


————————————————
版权声明:本文为CSDN博主「$9420」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sanri1993/article/details/100168530

发布了51 篇原创文章 · 获赞 80 · 访问量 93万+

猜你喜欢

转载自blog.csdn.net/xiyang_1990/article/details/103093316
今日推荐