修改 http message 序列化方式 (fastjson -> jackson).
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
package com.orion.ops.framework.desensitize.config;
|
||||
|
||||
import com.alibaba.fastjson.serializer.SerializeFilter;
|
||||
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import com.orion.lang.utils.Arrays1;
|
||||
import com.orion.ops.framework.desensitize.core.filter.DesensitizeValueSerializeFilter;
|
||||
import com.orion.ops.framework.common.constant.AutoConfigureOrderConst;
|
||||
import com.orion.ops.framework.desensitize.core.filter.DesensitizeValueFilter;
|
||||
import com.orion.ops.framework.desensitize.core.serializer.DesensitizeJsonSerializer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
|
||||
/**
|
||||
* 数据脱敏置类
|
||||
@@ -20,32 +19,25 @@ import org.springframework.context.annotation.Bean;
|
||||
* @since 2023/6/29 16:55
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@AutoConfigureAfter(name = "com.orion.ops.framework.web.config.OrionWebAutoConfiguration")
|
||||
@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_DESENSITIZE)
|
||||
public class OrionDesensitizeAutoConfiguration {
|
||||
|
||||
/**
|
||||
* @return 返回 序列化脱敏过滤器
|
||||
* @return fastjson 序列化脱敏过滤器
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnBean(FastJsonHttpMessageConverter.class)
|
||||
public DesensitizeValueSerializeFilter desensitizeValueSerializeFilter(FastJsonHttpMessageConverter converter) {
|
||||
DesensitizeValueSerializeFilter desensitizeFilter = new DesensitizeValueSerializeFilter();
|
||||
// 获取 json 配置
|
||||
FastJsonConfig config = converter.getFastJsonConfig();
|
||||
SerializeFilter[] filters = config.getSerializeFilters();
|
||||
int filterLength = Arrays1.length(filters);
|
||||
if (filterLength == 0) {
|
||||
// 未设置配置
|
||||
filters = new SerializeFilter[]{desensitizeFilter};
|
||||
} else {
|
||||
SerializeFilter[] newFilters = new SerializeFilter[filterLength + 1];
|
||||
System.arraycopy(filters, 0, newFilters, 0, filterLength);
|
||||
newFilters[filterLength] = desensitizeFilter;
|
||||
filters = newFilters;
|
||||
}
|
||||
// 更新到配置
|
||||
config.setSerializeFilters(filters);
|
||||
return desensitizeFilter;
|
||||
public DesensitizeValueFilter desensitizeValueFilter() {
|
||||
return new DesensitizeValueFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return jackson 序列化脱敏过滤器
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnBean(MappingJackson2HttpMessageConverter.class)
|
||||
public DesensitizeJsonSerializer desensitizeJsonSerializer(MappingJackson2HttpMessageConverter converter) {
|
||||
DesensitizeJsonSerializer serializer = new DesensitizeJsonSerializer();
|
||||
return serializer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
package com.orion.ops.framework.common.annotation;
|
||||
package com.orion.ops.framework.desensitize.core.annotation;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.orion.ops.framework.desensitize.core.serializer.DesensitizeJsonSerializer;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@@ -14,6 +18,8 @@ import java.lang.annotation.*;
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@JacksonAnnotationsInside
|
||||
@JsonSerialize(using = DesensitizeJsonSerializer.class)
|
||||
public @interface Desensitize {
|
||||
|
||||
/**
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.orion.ops.framework.common.annotation;
|
||||
package com.orion.ops.framework.desensitize.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@@ -8,8 +8,8 @@ import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.collect.Maps;
|
||||
import com.orion.lang.utils.reflect.Annotations;
|
||||
import com.orion.lang.utils.reflect.Fields;
|
||||
import com.orion.ops.framework.common.annotation.Desensitize;
|
||||
import com.orion.ops.framework.common.annotation.DesensitizeObject;
|
||||
import com.orion.ops.framework.desensitize.core.annotation.Desensitize;
|
||||
import com.orion.ops.framework.desensitize.core.annotation.DesensitizeObject;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
@@ -17,13 +17,15 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 脱敏序列化器
|
||||
* fastjson 脱敏序列化器
|
||||
* <p>
|
||||
* 用于全局日志打印
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/6/30 12:19
|
||||
*/
|
||||
public class DesensitizeValueSerializeFilter implements ValueFilter {
|
||||
public class DesensitizeValueFilter implements ValueFilter {
|
||||
|
||||
private static final Map<String, Map<String, Desensitize>> DESENSITIZE_FIELDS = new HashMap<>();
|
||||
|
||||
@@ -32,7 +34,7 @@ public class DesensitizeValueSerializeFilter implements ValueFilter {
|
||||
if (object == null || value == null) {
|
||||
return value;
|
||||
}
|
||||
Desensitize config = doDesensitizeField(object, name);
|
||||
Desensitize config = this.doDesensitizeField(object, name);
|
||||
// 无需脱敏
|
||||
if (config == null) {
|
||||
return value;
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.orion.ops.framework.desensitize.core.serializer;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.BeanProperty;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||
import com.orion.lang.utils.Desensitizes;
|
||||
import com.orion.lang.utils.Objects1;
|
||||
import com.orion.ops.framework.desensitize.core.annotation.Desensitize;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* jackson 脱敏序列化器
|
||||
* <p>
|
||||
* 用于 http 响应
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/11 17:10
|
||||
*/
|
||||
public class DesensitizeJsonSerializer extends JsonSerializer<Object> implements ContextualSerializer {
|
||||
|
||||
private Desensitize desensitize;
|
||||
|
||||
@Override
|
||||
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
|
||||
Desensitize desensitize = property.getAnnotation(Desensitize.class);
|
||||
if (Objects.nonNull(desensitize)) {
|
||||
this.desensitize = desensitize;
|
||||
return this;
|
||||
}
|
||||
return prov.findValueSerializer(property.getType(), property);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
// 为空判断
|
||||
if (value == null) {
|
||||
gen.writeNull();
|
||||
return;
|
||||
}
|
||||
// 脱敏
|
||||
String mix = Desensitizes.mix(Objects1.toString(value), desensitize.keepStart(), desensitize.keepEnd(), desensitize.replacer());
|
||||
gen.writeString(mix);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,8 +62,8 @@ public abstract class AbstractLogPrinterInterceptor implements LogPrinterInterce
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
@Autowired(required = false)
|
||||
@Qualifier("desensitizeValueSerializeFilter")
|
||||
private ValueFilter desensitizeValueSerializeFilter;
|
||||
@Qualifier("desensitizeValueFilter")
|
||||
private ValueFilter desensitizeValueFilter;
|
||||
|
||||
public AbstractLogPrinterInterceptor(LogPrinterConfig config) {
|
||||
this.config = config;
|
||||
@@ -89,8 +89,8 @@ public abstract class AbstractLogPrinterInterceptor implements LogPrinterInterce
|
||||
fieldFilterList.add(ignoreFilter);
|
||||
fieldFilterList.add(desensitizeFilter);
|
||||
// 注解脱敏 未引入
|
||||
if (desensitizeValueSerializeFilter != null) {
|
||||
fieldFilterList.add(desensitizeValueSerializeFilter);
|
||||
if (desensitizeValueFilter != null) {
|
||||
fieldFilterList.add(desensitizeValueFilter);
|
||||
}
|
||||
this.fieldFilters = fieldFilterList.toArray(new SerializeFilter[0]);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,27 @@
|
||||
package com.orion.ops.framework.web.config;
|
||||
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.ops.framework.common.constant.AutoConfigureOrderConst;
|
||||
import com.orion.ops.framework.common.constant.FilterOrderConst;
|
||||
import com.orion.ops.framework.common.filter.FilterCreator;
|
||||
import com.orion.ops.framework.web.core.convert.CustomerFastJsonHttpMessageConverter;
|
||||
import com.orion.ops.framework.web.core.convert.SerializeConfig;
|
||||
import com.orion.ops.framework.web.core.filter.TraceIdFilter;
|
||||
import com.orion.ops.framework.web.core.handler.GlobalExceptionHandler;
|
||||
import com.orion.ops.framework.web.core.handler.WrapperResultHandler;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceRegionHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -48,7 +45,7 @@ import java.util.List;
|
||||
* @since 2023/6/16 16:26
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(SerializeConfig.class)
|
||||
@AutoConfigureOrder(AutoConfigureOrderConst.FRAMEWORK_WEB)
|
||||
public class OrionWebAutoConfiguration implements WebMvcConfigurer {
|
||||
|
||||
@Value("${orion.api.prefix}")
|
||||
@@ -78,39 +75,6 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer {
|
||||
return new WrapperResultHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param serializeConfig 序列化配置
|
||||
* @return http message fast json 转换器
|
||||
*/
|
||||
@Bean
|
||||
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter(SerializeConfig serializeConfig) {
|
||||
// json 转换器
|
||||
CustomerFastJsonHttpMessageConverter converter = new CustomerFastJsonHttpMessageConverter(serializeConfig);
|
||||
// 配置
|
||||
FastJsonConfig config = new FastJsonConfig();
|
||||
// 支持的类型
|
||||
List<MediaType> mediaTypes = Lists.of(
|
||||
MediaType.APPLICATION_JSON,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
MediaType.APPLICATION_XHTML_XML,
|
||||
MediaType.TEXT_PLAIN,
|
||||
MediaType.TEXT_HTML,
|
||||
MediaType.TEXT_XML
|
||||
);
|
||||
converter.setSupportedMediaTypes(mediaTypes);
|
||||
// 序列化配置
|
||||
config.setSerializerFeatures(
|
||||
SerializerFeature.DisableCircularReferenceDetect,
|
||||
SerializerFeature.WriteMapNullValue,
|
||||
SerializerFeature.WriteNullListAsEmpty,
|
||||
SerializerFeature.IgnoreNonFieldGetter
|
||||
);
|
||||
config.setCharset(StandardCharsets.UTF_8);
|
||||
converter.setFastJsonConfig(config);
|
||||
converter.setDefaultCharset(StandardCharsets.UTF_8);
|
||||
return converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return http message jackson 转换器
|
||||
*/
|
||||
@@ -125,9 +89,11 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer {
|
||||
MediaType.TEXT_PLAIN,
|
||||
MediaType.TEXT_HTML,
|
||||
MediaType.TEXT_XML,
|
||||
new MediaType("application", "vnd.spring-boot.actuator.v2+json")
|
||||
MediaType.ALL
|
||||
);
|
||||
converter.setSupportedMediaTypes(mediaTypes);
|
||||
converter.setDefaultCharset(StandardCharsets.UTF_8);
|
||||
// 默认 objectMapper
|
||||
ObjectMapper objectMapper = converter.getObjectMapper();
|
||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
// 序列化配置
|
||||
@@ -142,18 +108,14 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer {
|
||||
* @return http message 转换器列表
|
||||
*/
|
||||
@Bean
|
||||
public HttpMessageConverters httpMessageConverters(FastJsonHttpMessageConverter fastJsonConverter,
|
||||
MappingJackson2HttpMessageConverter jacksonConvert) {
|
||||
List<HttpMessageConverter<?>> defaultConverters = new HttpMessageConverters().getConverters();
|
||||
public HttpMessageConverters httpMessageConverters(MappingJackson2HttpMessageConverter jacksonConvert) {
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||
// 将 byte converter 添加至首位 - fix swagger api 返回base64报错
|
||||
// 添加 byte converter - swagger api
|
||||
converters.add(new ByteArrayHttpMessageConverter());
|
||||
// 添加自定义 converter - using WrapperResultHandler/脱敏
|
||||
converters.add(fastJsonConverter);
|
||||
// 添加自定义 converter - jackson
|
||||
// 添加 resource region - admin api log
|
||||
converters.add(new ResourceRegionHttpMessageConverter());
|
||||
// 添加 json converter - jackson
|
||||
converters.add(jacksonConvert);
|
||||
// 添加默认处理器
|
||||
converters.addAll(defaultConverters);
|
||||
return new HttpMessageConverters(false, converters);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.orion.ops.framework.web.core.convert;
|
||||
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义 fastjson 转换器
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/11 11:46
|
||||
*/
|
||||
public class CustomerFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
|
||||
|
||||
private final SerializeConfig serializeConfig;
|
||||
|
||||
public CustomerFastJsonHttpMessageConverter(SerializeConfig serializeConfig) {
|
||||
this.serializeConfig = serializeConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
|
||||
List<String> unsupportedClasses = serializeConfig.getUnsupportedClasses();
|
||||
if (unsupportedClasses != null) {
|
||||
if (unsupportedClasses.contains(contextClass.getName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return super.canRead(type, contextClass, mediaType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
|
||||
return super.canWrite(type, clazz, mediaType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.orion.ops.framework.web.core.convert;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 序列化配置
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/11 14:57
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("orion.serializer")
|
||||
public class SerializeConfig {
|
||||
|
||||
/**
|
||||
* 不支持的序列化类型
|
||||
*/
|
||||
private List<String> unsupportedClasses;
|
||||
|
||||
public SerializeConfig() {
|
||||
this.unsupportedClasses = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,11 +14,6 @@
|
||||
"name": "orion.api.cors",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "是否开启 cors 过滤器."
|
||||
},
|
||||
{
|
||||
"name": "orion.serializer.unsupported-classes",
|
||||
"type": "java.util.List",
|
||||
"description": "不支持的序列化类型."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -133,11 +133,6 @@ orion:
|
||||
prefix: /orion-api
|
||||
# 是否开启跨域
|
||||
cors: true
|
||||
serializer:
|
||||
# 不支持的序列化类型
|
||||
unsupported-classes:
|
||||
- de.codecentric.boot.admin.server.web.InstancesController
|
||||
- org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler
|
||||
swagger:
|
||||
# swagger 配置
|
||||
title: orion-ops-pro 运维平台
|
||||
|
||||
Reference in New Issue
Block a user