01 原因

在数据库表结构设计过程中,常常使用status来表示当前记录的状态。返回给前端时,有时候需要后端手动调用查询数据库,返回字典翻译后的值,此操作过于麻烦。所以想使用的一个便捷的方式。

02 原理

JSON序列化时,将翻译后的值从字典中取出,动态添加到返回的的数据内

03 实现

项目采用Spring boot + Mybatis plus 进行开发 故采用了mybiatis plus的枚举接口

3.1 定义一个通用字典枚举,集成mybatis plus的IEnum

import com.baomidou.mybatisplus.core.enums.IEnum;
import com.fasterxml.jackson.annotation.JsonValue;
import java.io.Serializable;



/**
 * @description: 通用字典枚举
 * @author: wsat
 * @create: 2019-07-04 11:56
 **/
public interface IDictEnum<T extends Serializable> extends IEnum<T> {

    /**
     * 数据库中存储的值
     * @return
     */
    @JsonValue
    @Override
    T getValue();


    /**
     * 从数据库保存的字典ID
     * @return
     */
    String getDictCode();
    
}

3.2  实现该枚举

public enum  RoleEnum implements IDictEnum<String> {
    /**
     * 管理员
     */
    ADMIN("admin"),
    /**
     * 医生
     */
    DOCTOR("doctor");


    public final static String DICT_CODE="ROLE";

    RoleEnum(final String roleId){
        this.value=roleId;
    }

    public String value;

    @Override
    public String getValue() {
        return value;
    }

    @Override
    public String getDictCode() {
        return DICT_CODE;
    }
}

3. 3 生成一个Model

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user")
@ApiModel(value="User对象", description="")
public class User extends Model<User>  {

    private static final long serialVersionUID = 1L;

    @TableId(value = "user_id", type = IdType.ID_WORKER)
    private Integer userId;

    @ApiModelProperty(value = "手机号")
    @TableField("phone")
    private String phone;


    @ApiModelProperty(value = "密码")
    @TableField("password")
    @JsonIgnore
    private String password;


    @ApiModelProperty(value = "角色")
    @TableField("role")
    private RoleEnum role;
}

3.4 Mybiatis Plus 枚举转化配置 mybatis plus版本号 3.1.1

mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler
  type-enums-package: com.fidt.oims.module.system.model.enums

3.5 Jackson 添加IDictEnum序列化

public class DictEnumWebSerializer extends JsonSerializer<IDictEnum> {
    @Override
    public void serialize(IDictEnum value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException {
        if(value==null){
            jgen.writeNull();

        }
        jgen.writeObject(value.getValue());
        jgen.writeFieldName(jgen.getOutputContext().getCurrentName()+"Name");
        jgen.writeString(getEnumDesc(value));
    }

    @Override
    public Class handledType() {
        return IDictEnum.class;
    }

    private  String getEnumDesc(IDictEnum dictEnum){
        //此处从缓存中读取字典的信息
        return DictManger.getDictName(dictEnum.getDictCode(),dictEnum.getValue());
    }
}

3.6  添加到DictEnumWebSerializer到ObjectMapper内

@Configuration
public class WebConfig implements WebMvcConfigurer {

    
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters){
       converters.stream().filter(converter->converter instanceof MappingJackson2HttpMessageConverter).forEach(converter->{
           MappingJackson2HttpMessageConverter jsonConverter = (MappingJackson2HttpMessageConverter)converter;
           DictEnumWebSerializer dictEnumSerializer = new DictEnumWebSerializer();
           SimpleModule simpleModule = new SimpleModule();
           simpleModule.addSerializer(dictEnumSerializer);
           jsonConverter.getObjectMapper().registerModule(simpleModule);
       });
    }

}

04 展示