springboot序列化转换字典翻译

开发一个接口返回前端通常是直接序列化对象成json的,字典翻译需要提前转换好。例如通常返回前端:

{
  "id": 66,
  "nickname": "lingkang",
  "type": 2
}

缺少字典翻译 type手动添加过于繁杂,我们希望在序列化时自动翻译:

{
  "id": 66,
  "nickname": "lingkang",
  "type": 2,
  "typeName": "超级管理员"
}

下面我使用属性注解方案实现,环境:

  • springboot 2.x

定义字典注解

/**
 * @author lingkang
 * created by 2025-11-05
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DictConvert {
    /**
     * 字典key
     */
    String value() default "";
}

定义序列化字典翻译实现


/**
 * @author lingkang
 * created by 2025-11-05
 */
@Component
public class DictConvertSerialize extends StdScalarSerializer<Object> {
    public DictConvertSerialize() {
        this(Object.class);
    }

    public DictConvertSerialize(Class<Object> t) {
        super(t);
    }

    private static final Map<Field, DictConvert> cache = new ConcurrentHashMap<>();

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeObject(value);// 写入原值

        if (value != null) {
            JsonStreamContext context = gen.getOutputContext();
            Class<?> voClass = context.getCurrentValue().getClass();
            try {
                Field field = voClass.getDeclaredField(context.getCurrentName());
                DictConvert dictConvert = field.getAnnotation(DictConvert.class);
                if (dictConvert == null || dictConvert.value().isEmpty()) {
                    return;
                }

                DictConvert convert = cache.get(field);
                // 将字典key转化为name、例如从缓存中取
                String dictKey = dictConvert.value();
                System.out.println("字典key:" + dictKey);

                gen.writeFieldName("typeName");
                gen.writeString("user_type".equals(dictKey) ? "超级管理员" : "普通");// 写入字典翻译
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

使用注解到VO对象

/**
 * @author lingkang
 * created by 2025-11-05
 */
@Data
public class UserVO {
    private Long id;
    private String nickname;
    
    @DictConvert("user_type")// 自定义字典翻译
    @JsonSerialize(using = DictConvertSerialize.class)// 序列化实现
    private Integer type;
}

使用

开发一个简单接口看看效果

@RestController
public class WebController {
    @GetMapping({"/demo", "", "/"})
    public Object demo() {
        UserVO vo = new UserVO();
        vo.setId(66L);
        vo.setNickname("lingkang");
        vo.setType(2);
        return vo;
    }
}

调用时正确返回

{
  "id": 66,
  "nickname": "lingkang",
  "type": 2,
  "typeName": "超级管理员"
}

效果图:
image