why

In the process of database table structure design, status is often used to represent the status of the current record. When returned to the front end, it sometimes requires the back end to manually call the query database to return the dictionary translated value, which is too cumbersome. So want to use a convenient way.

The principle of

JSON serialization takes the translated value out of the dictionary and dynamically adds it to the returned data

implementation

The project adopts Spring Boot + Mybatis Plus for development, so the enumeration interface 1 of Mybiatis Plus is adopted. Define a generic dictionary enumeration that integrates the IEnum of Mybatis Plus

import com.baomidou.mybatisplus.core.enums.IEnum; import com.fasterxml.jackson.annotation.JsonValue; import java.io.Serializable; /** * @description: generic dictionary enumeration * @author: wsat * @create: 2019-07-04 11:56 **/ Public interface extends Serializable> extends IEnum<T> {public interface extends Serializable> extends IEnum<T>return*/ @JsonValue @Override T getValue(); /** * The dictionary ID * @ saved from the databasereturn
     */
    String getDictCode();
    
}
Copy the code
  1. Implement the enumeration
Public enum RoleEnum implements IDictEnum<String> {/** * ADMIN */ ADMIN("admin"), /** ** DOCTOR */ 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() {
        returnDICT_CODE; }}Copy the code
  1. Generate a Model
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user")
@ApiModel(value="The User object", 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 = "Mobile phone Number")
    @TableField("phone")
    private String phone;


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


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

Copy the code
  1. Mybiatis Plus version 3.1.1(If earlier than 3.1.0, please change the default-enum-type-handler to see the official web site) Application. yml
mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler
  type-enums-package: com.fidt.oims.module.system.model.enums
Copy the code
  1. Jackson added IDictEnum serialization
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() {
        returnIDictEnum.class; } private String getEnumDesc(IDictEnum dictEnum){// Read the dictionary information from the cachereturnDictManger.getDictName(dictEnum.getDictCode(),dictEnum.getValue()); }}Copy the code
  1. Add DictEnumWebSerializer to 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);
       });
    }

}
Copy the code
  1. Spring Boot front end receives enumeration directly
@Component
public class IDictEnumConvertFactory implements ConverterFactory<String, IDictEnum> {
    @Override
    public <T extends IDictEnum> Converter<String, T> getConverter(Class<T> targetType) {
        return new StringToIEum<>(targetType);
    }

    @SuppressWarnings("all")
    private static class StringToIEum<T extends IDictEnum> implements Converter<String, T> {
        private Class<T> targerType;

        public StringToIEum(Class<T> targerType) {
            this.targerType = targerType;
        }
        @Override
        public T convert(String source) {
            if (StrUtil.isEmpty(source)) {
                return null;
            }
            return (T) IDictEnumConvertFactory.getIEnum(this.targerType, source);
        }
    }
    
    public static <T extends IDictEnum> Object getIEnum(Class<T> targerType, String source) {
        for (T enumObj : targerType.getEnumConstants()) {
            if (source.equals(String.valueOf(enumObj.getValue()))) {
                returnenumObj; }}returnnull; }}Copy the code

show

code

Github