老鬼的博客 来都来啦,那就随便看看吧~
springboot过滤一些不需要返回的字段
发布于: 2022-10-13 更新于: 2022-11-03 分类于:  阅读次数: 

一:介绍

1
2
3
针对一些返回的json数据,可能是一些实体类,
并不想返回的字段也会一并返回出去,比如:id,
insert_time等,这里做一下处理

二:方法

2.1 定义注解

  • JsonFieldFilter.java
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
package com.tohours.cnTools.annotation;



import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @desc JSON 过滤自定义注解
* @author RenJie
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonFieldFilter {

Class<?> type();// 对哪个类的属性进行过滤

String include() default "";// 包含哪些字段,即哪些字段可以显示

String exclude() default "";// 不包含哪些字段,即哪些字段不可以显示

}

2.2 定义JSON序列化

  • MyJsonFilterSerializer.java
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
package com.tohours.cnTools.handler;

import java.io.IOException;
import java.lang.reflect.Field;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

public class MyJsonFilterSerializer {
private static final String DYNC_INCLUDE = "DYNC_INCLUDE";// 包含的标识
private static final String DYNC_EXCLUDE = "DYNC_EXCLUDE";// 过滤的标识
private ObjectMapper mapper = new ObjectMapper();

@JsonFilter(DYNC_EXCLUDE)
interface DynamicExclude {
}

@JsonFilter(DYNC_INCLUDE)
interface DynamicInclude {
}

public void filter(Class<?> clazz, String include, String exclude) {
if (clazz == null)
return;
if (include != null && include.length() > 0) {
// 包含的操作
mapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_INCLUDE,
SimpleBeanPropertyFilter.filterOutAllExcept(include.split(","))));
// 多个字段用,分割开
mapper.addMixIn(clazz, DynamicInclude.class);
} else if (exclude != null && exclude.length() > 0) {
mapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_EXCLUDE,
SimpleBeanPropertyFilter.serializeAllExcept(exclude.split(","))));
mapper.addMixIn(clazz, DynamicExclude.class);
}
// 日期格式化
JavaTimeModule javaTimeModule = new JavaTimeModule();
String pattern = "yyyy-MM-dd HH:mm:ss";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
javaTimeModule.addSerializer(new LocalDateTimeSerializer(formatter));

// 处理一下字段为空的时候的返回值
mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object o, JsonGenerator gen, SerializerProvider serializers) throws IOException {
String fieldName = gen.getOutputContext().getCurrentName();
try {
// Reflection get field type
Field field = gen.getCurrentValue().getClass().getDeclaredField(fieldName);
if (Objects.equals(field.getType(), String.class)) {
// 空字符串返回 ""
gen.writeString("");
return;
} else if (Objects.equals(field.getType(), List.class)) {
// 空list返回 []
gen.writeStartArray();
gen.writeEndArray();
return;
} else if (Objects.equals(field.getType(), Map.class)) {
// 空map返回 {}
gen.writeStartObject();
gen.writeEndObject();
return;
} else if (Objects.equals(field.getType(), Object.class)) {
// 空Object返回 {}
gen.writeStartObject();
gen.writeEndObject();
return;
}
} catch (NoSuchFieldException e) {
}
gen.writeString("");
}

});
mapper.registerModule(javaTimeModule);
}

public String toJson(Object object) throws JsonProcessingException {
return mapper.writeValueAsString(object);
}

@SuppressWarnings("rawtypes")
public static void main(String[] args) throws JsonProcessingException {

MyJsonFilterSerializer cjs = new MyJsonFilterSerializer();
// 只包含 id, name
cjs.filter(HashMap.class, "id,name", null);
HashMap<String, String> test = new HashMap<>();
test.put("nxx", "nxx");
test.put("id", "nxx");
test.put("name", "nxx");
String include = cjs.toJson(test);
System.out.println("include: " + include);

cjs = new MyJsonFilterSerializer();
// 过滤掉 id, name
cjs.filter(HashMap.class, null, "childKey");

HashMap<String, HashMap> test2 = new HashMap<>();
HashMap<String, String> child = new HashMap<>();
child.put("childKey", "childValue");
test2.put("nxx", null);
String filter = cjs.toJson(test2);
System.out.println("filter: " + filter);

}
}


2.3 拦截Response响应

  • MyResponseBodyAdvice.java
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
package com.tohours.cnTools.handler;

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.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.tohours.cnTools.annotation.JsonFieldFilter;

import lombok.extern.slf4j.Slf4j;


/**
* @desc 拦截返回值,排除或者包含某些字段
* @author RenJie
* @date 2022-10-08
*
*/
@ControllerAdvice
@Slf4j
public class MyResponseBodyAdvice implements ResponseBodyAdvice<Object> {

/**
* supports方法是来给定条件判断是否该调用beforeBodyWrite,MethodParameter里面有各种数据,
**/
@SuppressWarnings("rawtypes")
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return true;
}

/**
* 响应结果拦截根据业务去封装返回体
**/
@SuppressWarnings("rawtypes")
@Override
public Object beforeBodyWrite(Object returnObject, MethodParameter paramter, MediaType mediaType, Class aClass,
ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
log.info("构造结果" + JSON.toJSONString(returnObject));

// 判定是否有JsonFieldFilter注解,则过滤返回的对象returnObject
if (paramter.hasMethodAnnotation(JsonFieldFilter.class)) {
MyJsonFilterSerializer serializer = new MyJsonFilterSerializer();
JsonFieldFilter jsonFilter = paramter.getMethodAnnotation(JsonFieldFilter.class);
String include = jsonFilter.include();
String enclude = jsonFilter.exclude();
log.info("include:" + include);
log.info("enclude:" + enclude);
serializer.filter(jsonFilter.type() == null ? returnObject.getClass() : jsonFilter.type(),
include, enclude);// 调用过滤方法
try {
//解析
return JSONObject.parse(serializer.toJson(returnObject));
} catch (JsonProcessingException e) {
log.error("json过滤异常",e);
}
}
//默认返回全部的值
return returnObject;

}
}
*************感谢您的阅读*************