【7.2.5】【wrapper】优化针对json响应数据的自定义格式化

pull/37/head
fengshuonan 2022-09-06 16:06:27 +08:00
parent aeaf4936be
commit f053734a35
9 changed files with 222 additions and 6 deletions

View File

@ -45,11 +45,11 @@ public @interface JsonFieldFormat {
* <p>
*
*/
FormatTypeEnum formatType() default FormatTypeEnum.WRAPPER;
FormatTypeEnum formatType() default FormatTypeEnum.ADD_FIELD;
/**
*
*/
Class<? extends JsonFieldFormatProcess> process();
Class<? extends JsonFieldFormatProcess> processClass();
}

View File

@ -11,15 +11,15 @@ public enum FormatTypeEnum {
/**
*
* <p>
* userId=1001userId=
* userId=1001userId=
*/
REPLACE,
/**
* +Wrapper"
* +Wrapper"
* <p>
* userId=1001userIdWrapper=
* userId=1001userId=1001userIdWrapper=
*/
WRAPPER
ADD_FIELD
}

View File

@ -17,6 +17,7 @@
<modules>
<module>wrapper-api</module>
<module>wrapper-field-sdk</module>
<module>wrapper-sdk</module>
<module>wrapper-spring-boot-starter</module>
</modules>

View File

@ -42,4 +42,9 @@ public interface WrapperConstants {
*/
String WRAPPER_EXCEPTION_STEP_CODE = "24";
/**
*
*/
String FILED_WRAPPER_SUFFIX = "Wrapper";
}

View File

@ -0,0 +1,31 @@
# 字段转化模块
通过json的序列化定制将ID或者枚举值相关的字段转化成可以前段直接读懂的名称
## 示例1
http响应时转化userId为用户的名字
Long userId; -> "张三"
## 示例2
http响应时转化status为状态的名字
Integer status; -> "启用"
## 示例3
http响应时转化枚举为对应的名称
StatusEnum status; -> "禁用"
## 示例4
http响应时转化一组数组
List<Long> userIdList; -> ["张三","李四","王五"]
## 其他拓展
只要按接口规范,可以拓展任何相关值的转化

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-wrapper</artifactId>
<version>7.2.5</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>wrapper-field-sdk</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--wrapper模块的api-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>wrapper-api</artifactId>
<version>${roses.version}</version>
</dependency>
<!--jackson相关基础依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,41 @@
package cn.stylefeng.roses.kernel.wrapper.field;
import cn.stylefeng.roses.kernel.rule.annotation.JsonFieldFormat;
import cn.stylefeng.roses.kernel.rule.base.JsonFieldFormatProcess;
import cn.stylefeng.roses.kernel.rule.enums.FormatTypeEnum;
import cn.stylefeng.roses.kernel.wrapper.field.serializer.CustomJsonSerializer;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
/**
* Json@JsonFieldFormat
*
* @author fengshuonan
* @date 2022/9/6 13:56
*/
public class CustomJacksonIntrospector extends JacksonAnnotationIntrospector {
/**
*
*/
private static final long serialVersionUID = 3159434791568421355L;
@Override
public Object findSerializer(Annotated annotated) {
JsonFieldFormat formatter = annotated.getAnnotation(JsonFieldFormat.class);
if (formatter == null || formatter.processClass() == null) {
return super.findSerializer(annotated);
}
// 获取格式化处理的方式
FormatTypeEnum formatTypeEnum = formatter.formatType();
// 获取具体的处理方法
Class<? extends JsonFieldFormatProcess> process = formatter.processClass();
// 创建对应的序列化模式
return new CustomJsonSerializer(formatTypeEnum, process);
}
}

View File

@ -0,0 +1,96 @@
package cn.stylefeng.roses.kernel.wrapper.field.serializer;
import cn.hutool.core.util.ClassUtil;
import cn.stylefeng.roses.kernel.rule.base.JsonFieldFormatProcess;
import cn.stylefeng.roses.kernel.rule.enums.FormatTypeEnum;
import cn.stylefeng.roses.kernel.wrapper.api.constants.WrapperConstants;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.lang.reflect.Field;
/**
* @JsonFieldFormat
*
* @author fengshuonan
* @date 2022/9/6 14:09
*/
@Slf4j
public class CustomJsonSerializer extends JsonSerializer<Object> {
/**
* wrapper
*/
private final FormatTypeEnum formatTypeEnum;
/**
*
*/
private final Class<? extends JsonFieldFormatProcess> processClass;
public CustomJsonSerializer(FormatTypeEnum formatTypeEnum, Class<? extends JsonFieldFormatProcess> processClass) {
this.formatTypeEnum = formatTypeEnum;
this.processClass = processClass;
}
@Override
public void serialize(Object originValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) {
// 序列化字段名称
String fieldName = jsonGenerator.getOutputContext().getCurrentName();
// 创建具体字段转化的实现类
JsonFieldFormatProcess jsonFieldFormatProcess = null;
try {
jsonFieldFormatProcess = processClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
log.error("执行json的字段序列化出错", e);
return;
}
// 判断当前字段值是否可以转化
boolean canFormat = jsonFieldFormatProcess.canFormat(originValue);
if (!canFormat) {
return;
}
// 执行转化,获取转化过的值
Object formattedValue = jsonFieldFormatProcess.formatProcess(originValue);
try {
// 如果转化模式是替换类型
if (formatTypeEnum.equals(FormatTypeEnum.REPLACE)) {
jsonGenerator.writeObject(formattedValue);
}
// 如果转化模式是新增一个包装字段
else {
// 先写入原有值,保持不变
jsonGenerator.writeObject(originValue);
// 构造新的字段名,为原字段名+Wrapper
String newWrapperFieldName = fieldName + WrapperConstants.FILED_WRAPPER_SUFFIX;
// 获取当前正在转化的对象
Object currentObj = jsonGenerator.getOutputContext().getCurrentValue();
// 如果当前正在转化的对象中已经含有了字段名+Wrapper的字段则生成时候带一个数字2
Field declaredField = ClassUtil.getDeclaredField(currentObj.getClass(), newWrapperFieldName);
if (declaredField != null) {
newWrapperFieldName = newWrapperFieldName + "2";
}
// 写入新的字段名
jsonGenerator.writeFieldName(newWrapperFieldName);
jsonGenerator.writeObject(formattedValue);
}
} catch (IOException e) {
log.error("执行json的字段序列化出错", e);
}
}
}

View File

@ -24,6 +24,13 @@
<version>${roses.version}</version>
</dependency>
<!--对字段的包装和转化-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>wrapper-field-sdk</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>