SpringBoot Jackson 数据字典映射

场景: 在设计数据库时,我们通常会建立一个dict表,存储了项目内所有的字典名称和字典值,例如用户等级、用户职称等字典,然后其他表内的存储的值是dict_code,前端展示需要将dict_code映射为dict_value。

示例: User表有个sourceType字段(1=微信、2=在发版),返回给前端时需要返回sourceType(dict_code),和sourceTypeName(dict_key)。

实现方案: 通过自定义JsonSerializer方式实现枚举值的动态转换。

  1. 定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DictTranslationSerialize.class)
public @interface DictTranslation {

    /**
    * 数据库内的 dict_key
    */
    String dictKey();

    /**
     * 转换后的json字段名称
     * @return
     */
    String targetFieldName() default "";

}
  1. 继承JsonSerializer,自定义序列化规则。
@AllArgsConstructor
@NoArgsConstructor
public class DictTranslationSerialize extends JsonSerializer<Object> implements ContextualSerializer {

    private String dictKey;
    private String sourceFieldName;
    private String fieldName;


    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        String codeValue = o.toString();
        jsonGenerator.writeString(codeValue);

        //模拟查询数据库 select * from dict where dict_key = #{dictKey};
        String dictValue = "dictValue="+dictKey;
        //如果没有指定生成的字段值,则去原字段的名字加Value后缀。
        fieldName = Objects.isNull(fieldName) || fieldName.trim().isEmpty() ? sourceFieldName+"Value" : fieldName;
        //写入json
        jsonGenerator.writeFieldName(fieldName);
        jsonGenerator.writeObject(dictValue);
        //还可以继续写其他的东西
        jsonGenerator.writeFieldName("serialized");
        jsonGenerator.writeObject(true);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            DictTranslation t = beanProperty.getAnnotation(DictTranslation.class);
            if (t != null) {
                return new DictTranslationSerialize(t.dictKey(), beanProperty.getName(), t.targetFieldName());
            }
        }
        return serializerProvider.findNullValueSerializer(beanProperty);
    }
}
  1. eneity类上添加注解
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Student {

    @DictTranslation(dictKey = "helloWorld")
    private String sourceType;
}

你可能感兴趣的:(springBoot,spring,boot,后端,java)