mirror of https://gitee.com/stylefeng/roses
【7.2.5】【wrapper】优化针对json响应数据的自定义格式化
parent
aeaf4936be
commit
f053734a35
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -11,15 +11,15 @@ public enum FormatTypeEnum {
|
|||
/**
|
||||
* 替换型,将原有字段替换成新的值
|
||||
* <p>
|
||||
* 例如:接口返回userId=1001,采用本种方式则返回userId=张三
|
||||
* 例如:接口返回userId=1001,采用本种方式则返回:userId=张三
|
||||
*/
|
||||
REPLACE,
|
||||
|
||||
/**
|
||||
* 包装型,不改变原来字段值,在同级别字段中,增加一个 “源字段名+Wrapper" 字段
|
||||
* 额外加字段,不改变原来字段值,在同级别字段中,增加一个 “源字段名+Wrapper" 字段
|
||||
* <p>
|
||||
* 例如:接口返回userId=1001,采用本种方式则返回userIdWrapper=张三
|
||||
* 例如:接口返回userId=1001,采用本种方式则返回:userId=1001,userIdWrapper=张三
|
||||
*/
|
||||
WRAPPER
|
||||
ADD_FIELD
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -42,4 +42,9 @@ public interface WrapperConstants {
|
|||
*/
|
||||
String WRAPPER_EXCEPTION_STEP_CODE = "24";
|
||||
|
||||
/**
|
||||
* 被包装字段,新建字段的结尾字段名
|
||||
*/
|
||||
String FILED_WRAPPER_SUFFIX = "Wrapper";
|
||||
|
||||
}
|
||||
|
|
|
@ -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; -> ["张三","李四","王五"]
|
||||
|
||||
## 其他拓展
|
||||
|
||||
只要按接口规范,可以拓展任何相关值的转化
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue