причина
В процессе проектирования структуры таблицы базы данных статус часто используется для представления статуса текущей записи. При возврате к интерфейсу иногда серверу необходимо вручную вызвать базу данных запросов, чтобы вернуть переведенное значение словаря, что слишком хлопотно. Так хочется использовать удобный способ.
принцип
Во время сериализации 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();
}
- Перечисление реализации
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;
}
}
- Генерировать модель
@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;
}
- Конфигурация преобразования перечисления 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
- Джексон добавляет сериализацию 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());
}
}
- В 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);
});
}
}
- Внешний интерфейс 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;
}
}