序列化的方式实现用注解进行字典翻译

在这里插入图片描述

序言

在我们日常开发中,时常会遇到需要字典翻译的情况,那么如何优雅的实现字典翻译呢?本文将介绍通过注解的方式,在序列化返回前端时,进行字典翻译。

需求背景

因为公司的业务表存的字典的id,所以字典翻译以此需求背景来开发。

依赖引入

1.集成spring-cache+redis作为我们缓存方案,翻译时,从缓存取数据,具体集成过程不过多赘述,感兴趣可以看我另外的分享文章。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
                <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

新增自定义注解

1.在@DictCode注解中,可以指定翻译后的字段名称。

@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD})
@JsonSerialize(using = DictSerialize.class)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JacksonAnnotation
public @interface DictCode {
    String fieldName() default "";
}

实现json序列化接口

1.如果不指定fieldName属性,则默认使用原字段名 + "Name"作为翻译后的字段名称。
2.如果指定了fieldName属性,则使用指定的字段名称作为翻译后的字段名称。
3.前端直接取fieldName属性中定义的字段即可。
在序列化过程中,DictSerialize序列化器会根据@DictCode注解的配置,远程调用字典服务获取翻译后的字段值,并将其添加到JSON中。
通过使用@DictCode注解,您可以方便地对需要进行字典翻译的字段进行配置,并在序列化过程中自动获取翻译后的字段值。
注:无需定义翻译后的字段,添加注解后,在序列化时,自动新增一个跟注解里面的fieldName名称相同的字段。如果没定义,默认是使用原字段名 + "Name"作为翻译后的字段名称。

package cn.healthlink.bmc.master.common.serialize;


import cn.healthlink.bmc.master.common.annotation.DictCode;
import cn.healthlink.bmc.system.api.feign.DictFeignClient;
import cn.healthlink.bmc.system.api.vo.DictVO;
import cn.springsoter.core.tool.api.R;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.util.Objects;

/**
 * @author HXQ
 */
@JsonComponent
@Slf4j
public class DictSerialize extends JsonSerializer<Long> implements ContextualSerializer {
    private final DictFeignClient dictFeignClient;
    String fieldName = "";

    public DictSerialize(DictFeignClient dictFeignClient) {
        this.dictFeignClient = Objects.requireNonNull(dictFeignClient, "dictFeignClient must not be null");
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
        //获取该字段上的dict注解
        DictCode dict = property.getAnnotation(DictCode.class);
        if (dict != null && StringUtils.isNotBlank(dict.fieldName())) {
            this.fieldName = dict.fieldName();
        } else {
            this.fieldName = property.getName() + "Name";
        }
        log.info("字典序列化时,字段名称:{}", fieldName);
        return this;
    }

    @Override
    public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeNumber(value);
        try {
            R<DictVO> dict = dictFeignClient.getDict(value);
            if (dict != null && dict.getData() != null) {
                log.info("字典值为:{}", dict.getData());
                gen.writeStringField(fieldName, dict.getData().getName());
            }
        } catch (Exception e) {
            log.error("远程调用获取字典内容失败", e);
            //处理远程调用异常,提供默认值或写入空值
            gen.writeStringField(fieldName, " ");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值