【7.2.5】【wrapper】增加对枚举类型的自定义转化过程

pull/37/head
fengshuonan 2022-09-06 17:46:47 +08:00
parent 4ac9637014
commit fb3b8cea00
5 changed files with 212 additions and 48 deletions

View File

@ -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.
*
* GunsAPACHE 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.*;
/**
* jsonSexEnum.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();
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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 jacksonjson
* @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);
}
}
}