0
点赞
收藏
分享

微信扫一扫

springboot自定义Json序列化返回,实现自动转换字典值

RIOChing 2023-09-21 阅读 16

自定义序列化
原理
当你使用Spring Boot的Spring Data或者Spring MVC等组件来处理JSON序列化时,Spring框架会在需要将Java对象转换为JSON字符串时调用JsonSerializer。这通常发生在控制器方法返回JSON响应时,或者在将对象保存到数据库等操作中。

// 注册到环境中
@Configuration
public class CustomJsonConverterConfig {
	@Bean
    public DictJsonSerializer serializer(ObjectMapper objectMapper) {
        final DictJsonSerializer dictJsonSerializer = new DictJsonSerializer();
        /*final BigDecimalSerializer bigDecimalSerializer = new BigDecimalSerializer();
        final DoubleSerializer doubleSerializer = new DoubleSerializer();*/
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(BaseDictVo.class, dictJsonSerializer);
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
//        simpleModule.addSerializer(BigDecimal.class, bigDecimalSerializer);
//        simpleModule.addSerializer(Double.class, doubleSerializer);
        objectMapper.registerModule(simpleModule);
        return dictJsonSerializer;
    }
}

跟基础平台不同,返回的是序列化类,而不是objectMapper

编写序列化实现类
(注意:只有当返回对象实现了BaseDictVo才会生效,避免对所有代码进行过滤,导致性能损耗)

public class DictJsonSerializer extends JsonSerializer<BaseDictVo> {
    /**
     * 自定义字典序列化
     *
     * @param source    字段值
     * @param generator Json 生成器
     * @param provider  Json 提供者
     * @throws IOException
     */
    @Override
    public void serialize(BaseDictVo source, JsonGenerator generator, SerializerProvider provider) throws IOException {
        // 写入JSON开头对象 {
        generator.writeStartObject();
        for (Field field : source.getClass().getDeclaredFields()) {
            final Object fieldValue = ReflectUtil.getFieldValue(source, field);
            final TransDict transDict = field.getDeclaredAnnotation(TransDict.class);
            if (Objects.isNull(fieldValue) || Objects.isNull(transDict)) {
                if (Objects.nonNull(fieldValue)) {
                    generator.writeObjectField(field.getName(), fieldValue);
                }
                continue;
            }
            // 字典编码
            final String dictCode = transDict.code();
            // 转换的目标字段
            final String targetFiledName = transDict.alias();
            if (StringUtils.isBlank(dictCode)) {
                generator.writeObjectField(field.getName(), fieldValue);
                continue;
            }
            // 字段转换
            final List<String> strings = Arrays.asList(StringUtils.split(fieldValue.toString(), ","));
            StringBuilder dictValues = new StringBuilder();
            final Iterator<String> iterator = strings.iterator();
            while (iterator.hasNext()) {
                String code = iterator.next();
                String val = DictUtil.convertDict(dictCode, code);
                if (StringUtils.isBlank(code) || StringUtils.isBlank(val)) {
                    continue;
                }
                dictValues.append(val);
                if (iterator.hasNext()) {
                    dictValues.append(",");
                }
            }
            // 目标字段存在则设置目标字段值,否则设置当前字段值
            if (StringUtils.isNotBlank(targetFiledName)) {
                generator.writeObjectField(field.getName(), fieldValue);
                generator.writeObjectField(targetFiledName, dictValues.toString());
            } else {
                generator.writeObjectField(field.getName(), dictValues.toString());
            }
        }
        // 写入JSON结尾对象 }
        generator.writeEndObject();
    }
}

定义注解
用以标记字段,获取字典的编码,以及指定的目标替换字段

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TransDict {
    String code() default "";


    String alias() default "";
}

定义基类
用以标记生效的类

public interface BaseDictVo {
}

使用类
使用注解示例

@Data
@ApiModel("反馈项vo")
public class CmFeedbackConfigVo implements BaseDictVo {

    @ApiModelProperty(value = "业务域编码(直饮水-DRINK、SUPPLY-供水)")
    @TransDict(code = "IAM_DOMAIN", alias = "businessDomainCodeValue")
    private String businessDomainCode;

    @ApiModelProperty(value = "业务域编码(直饮水-DRINK、SUPPLY-供水)")
    private String businessDomainCodeValue;
}

效果
每次前端发起请求时,因为RestController作用,会在返回时把结果序列化为Json,即触发自定义序列化类

举报

相关推荐

0 条评论