Spring Boot возвращает на основе внешнего интерфейса словаря перечисления

Spring Boot

причина

В процессе проектирования структуры таблицы базы данных статус часто используется для представления статуса текущей записи. При возврате к интерфейсу иногда серверу необходимо вручную вызвать базу данных запросов, чтобы вернуть переведенное значение словаря, что слишком хлопотно. Так хочется использовать удобный способ.

принцип

Во время сериализации JSON переведенное значение извлекается из словаря и динамически добавляется к возвращаемым данным.

выполнить

Проект разработан с использованием Spring boot + Mybatis plus, поэтому используется интерфейс перечисления mybiatis plus. 1. Определите общее перечисление словаря и интегрируйте IEnum в mybatis plus.

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();
    
}
  1. Перечисление реализации
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;
    }
}
  1. Генерировать модель
@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;
}

  1. Конфигурация преобразования перечисления Mybiatis Plus mybatis plus номер версии 3.1.1 (если версия ниже 3.1.0, измените обработчик типа по умолчанию-enum-type, подробности см. на официальном сайте) приложение.yml
mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler
  type-enums-package: com.fidt.oims.module.system.model.enums
  1. Джексон добавляет сериализацию 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());
    }
}
  1. В ObjectMapper добавлен DictEnumWebSerializer.
@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);
       });
    }

}
  1. Внешний интерфейс Spring Boot напрямую получает перечисление
@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()))) {
                return enumObj;
            }
        }
        return null;
    }
}

экспонат

код

Github