mirror of https://gitee.com/stylefeng/roses
【7.2.5】【wrapper】增加对枚举类型的自定义转化过程
parent
4ac9637014
commit
fb3b8cea00
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright [2020-2030] [https://www.stylefeng.cn]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Guns源码头部的版权声明。
|
||||
* 3.请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns
|
||||
* 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns
|
||||
* 6.若您的项目无法满足以上几点,可申请商业授权
|
||||
*/
|
||||
package cn.stylefeng.roses.kernel.rule.annotation;
|
||||
|
||||
import cn.stylefeng.roses.kernel.rule.base.ReadableEnum;
|
||||
import cn.stylefeng.roses.kernel.rule.enums.FormatTypeEnum;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* json字段的格式化,可以将枚举转化为可读性的值,例如:SexEnum.M -> "男",例如:"M" -> "男“
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2022/9/6 11:34
|
||||
*/
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface EnumFieldFormat {
|
||||
|
||||
/**
|
||||
* 字段格式化的类型 详情见:{@link FormatTypeEnum}
|
||||
* <p>
|
||||
* 默认采用包装型,不改变原有的字段
|
||||
*/
|
||||
FormatTypeEnum formatType() default FormatTypeEnum.ADD_FIELD;
|
||||
|
||||
/**
|
||||
* 具体处理值转化过程的枚举【必传】
|
||||
*/
|
||||
Class<? extends ReadableEnum> processEnum();
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package cn.stylefeng.roses.kernel.wrapper.field.enums;
|
||||
|
||||
import cn.stylefeng.roses.kernel.rule.base.ReadableEnum;
|
||||
import cn.stylefeng.roses.kernel.rule.enums.FormatTypeEnum;
|
||||
import cn.stylefeng.roses.kernel.wrapper.field.util.CommonFormatUtil;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 针对@EnumFieldFormat注解的具体序列化过程
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2022/9/6 16:57
|
||||
*/
|
||||
@Slf4j
|
||||
public class EnumFieldFormatSerializer extends JsonSerializer<Object> {
|
||||
|
||||
/**
|
||||
* 序列化类型,覆盖还是wrapper模式
|
||||
*/
|
||||
private final FormatTypeEnum formatTypeEnum;
|
||||
|
||||
/**
|
||||
* 具体序列化需要的枚举
|
||||
*/
|
||||
private final Class<? extends ReadableEnum> processEnum;
|
||||
|
||||
public EnumFieldFormatSerializer(FormatTypeEnum formatTypeEnum, Class<? extends ReadableEnum> processEnum) {
|
||||
this.formatTypeEnum = formatTypeEnum;
|
||||
this.processEnum = processEnum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object originValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) {
|
||||
|
||||
// 最终转化的值
|
||||
Object result = originValue;
|
||||
|
||||
// 如果原始字段是枚举类型,则直接调用接口的getName()方法完成转化
|
||||
if (originValue instanceof ReadableEnum) {
|
||||
result = ((ReadableEnum) originValue).getName();
|
||||
} else {
|
||||
|
||||
// 如果是其他类型,则获取枚举的getKey()的类型是什么
|
||||
// getKey()类型和值类型一致才能进行转化
|
||||
if (processEnum.isEnum()) {
|
||||
ReadableEnum[] enumConstants = processEnum.getEnumConstants();
|
||||
for (ReadableEnum enumConstant : enumConstants) {
|
||||
if (enumConstant.getKey().equals(originValue)) {
|
||||
result = enumConstant.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 进行数据转化写入到渲染的JSON中
|
||||
CommonFormatUtil.writeField(formatTypeEnum, originValue, result, jsonGenerator);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
package cn.stylefeng.roses.kernel.wrapper.field.jackson;
|
||||
|
||||
import cn.stylefeng.roses.kernel.rule.annotation.EnumFieldFormat;
|
||||
import cn.stylefeng.roses.kernel.rule.annotation.SimpleFieldFormat;
|
||||
import cn.stylefeng.roses.kernel.rule.base.ReadableEnum;
|
||||
import cn.stylefeng.roses.kernel.rule.base.SimpleFieldFormatProcess;
|
||||
import cn.stylefeng.roses.kernel.rule.enums.FormatTypeEnum;
|
||||
import cn.stylefeng.roses.kernel.wrapper.field.enums.EnumFieldFormatSerializer;
|
||||
import cn.stylefeng.roses.kernel.wrapper.field.simple.SimpleFieldFormatSerializer;
|
||||
import com.fasterxml.jackson.databind.introspect.Annotated;
|
||||
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
|
||||
|
@ -22,20 +25,34 @@ public class CustomJacksonIntrospector extends JacksonAnnotationIntrospector {
|
|||
|
||||
@Override
|
||||
public Object findSerializer(Annotated annotated) {
|
||||
SimpleFieldFormat formatter = annotated.getAnnotation(SimpleFieldFormat.class);
|
||||
|
||||
if (formatter == null || formatter.processClass() == null) {
|
||||
return super.findSerializer(annotated);
|
||||
// 自定义格式化过程
|
||||
SimpleFieldFormat simpleFieldFormat = annotated.getAnnotation(SimpleFieldFormat.class);
|
||||
if (simpleFieldFormat != null && simpleFieldFormat.processClass() != null) {
|
||||
// 获取格式化处理的方式
|
||||
FormatTypeEnum formatTypeEnum = simpleFieldFormat.formatType();
|
||||
|
||||
// 获取具体的处理方法
|
||||
Class<? extends SimpleFieldFormatProcess> process = simpleFieldFormat.processClass();
|
||||
|
||||
// 创建对应的序列化模式
|
||||
return new SimpleFieldFormatSerializer(formatTypeEnum, process);
|
||||
}
|
||||
|
||||
// 获取格式化处理的方式
|
||||
FormatTypeEnum formatTypeEnum = formatter.formatType();
|
||||
// 枚举格式化过程
|
||||
EnumFieldFormat enumFieldFormat = annotated.getAnnotation(EnumFieldFormat.class);
|
||||
if (enumFieldFormat != null && enumFieldFormat.processEnum() != null) {
|
||||
// 获取格式化处理的方式
|
||||
FormatTypeEnum formatTypeEnum = enumFieldFormat.formatType();
|
||||
|
||||
// 获取具体的处理方法
|
||||
Class<? extends SimpleFieldFormatProcess> process = formatter.processClass();
|
||||
// 获取具体的处理枚举
|
||||
Class<? extends ReadableEnum> process = enumFieldFormat.processEnum();
|
||||
|
||||
// 创建对应的序列化模式
|
||||
return new SimpleFieldFormatSerializer(formatTypeEnum, process);
|
||||
// 创建对应的序列化模式
|
||||
return new EnumFieldFormatSerializer(formatTypeEnum, process);
|
||||
}
|
||||
|
||||
return super.findSerializer(annotated);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package cn.stylefeng.roses.kernel.wrapper.field.simple;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.stylefeng.roses.kernel.rule.base.SimpleFieldFormatProcess;
|
||||
import cn.stylefeng.roses.kernel.rule.enums.FormatTypeEnum;
|
||||
import cn.stylefeng.roses.kernel.wrapper.api.constants.WrapperConstants;
|
||||
import cn.stylefeng.roses.kernel.wrapper.field.util.CommonFormatUtil;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 针对@SimpleFieldFormat注解的具体序列化过程
|
||||
*
|
||||
|
@ -39,9 +35,6 @@ public class SimpleFieldFormatSerializer extends JsonSerializer<Object> {
|
|||
@Override
|
||||
public void serialize(Object originValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) {
|
||||
|
||||
// 序列化字段名称
|
||||
String fieldName = jsonGenerator.getOutputContext().getCurrentName();
|
||||
|
||||
// 创建具体字段转化的实现类
|
||||
SimpleFieldFormatProcess simpleFieldFormatProcess = null;
|
||||
try {
|
||||
|
@ -60,37 +53,8 @@ public class SimpleFieldFormatSerializer extends JsonSerializer<Object> {
|
|||
// 执行转化,获取转化过的值
|
||||
Object formattedValue = simpleFieldFormatProcess.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);
|
||||
}
|
||||
// 将转化的值,根据策略,进行写入到渲染的json中
|
||||
CommonFormatUtil.writeField(formatTypeEnum, originValue, formattedValue, jsonGenerator);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package cn.stylefeng.roses.kernel.wrapper.field.util;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.stylefeng.roses.kernel.rule.enums.FormatTypeEnum;
|
||||
import cn.stylefeng.roses.kernel.wrapper.api.constants.WrapperConstants;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* 通用的格式化方法
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2022/9/6 17:14
|
||||
*/
|
||||
@Slf4j
|
||||
public class CommonFormatUtil {
|
||||
|
||||
/**
|
||||
* 根据格式化类型,将原始的json字段数据,进行包装转化为新的字段数据过程
|
||||
*
|
||||
* @param formatTypeEnum 格式化类型,是新增字段还是替换字段
|
||||
* @param originValue 原始的字段值
|
||||
* @param formattedValue 新产生的字段值
|
||||
* @param jsonGenerator jackson的写入json字段数据的工具类
|
||||
* @author fengshuonan
|
||||
* @date 2022/9/6 17:16
|
||||
*/
|
||||
public static void writeField(FormatTypeEnum formatTypeEnum, Object originValue, Object formattedValue, JsonGenerator jsonGenerator) {
|
||||
try {
|
||||
// 如果转化模式是替换类型
|
||||
if (formatTypeEnum.equals(FormatTypeEnum.REPLACE)) {
|
||||
jsonGenerator.writeObject(formattedValue);
|
||||
}
|
||||
|
||||
// 如果转化模式是新增一个包装字段
|
||||
else {
|
||||
// 先写入原有值,保持不变
|
||||
jsonGenerator.writeObject(originValue);
|
||||
|
||||
// 构造新的字段名,为原字段名+Wrapper
|
||||
String fieldName = jsonGenerator.getOutputContext().getCurrentName();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue