一、字典序列化器
实现自定义字典序列化注解,在对象进行序列化时,加载指定字典类型,并根据属性值匹配对应的字典项,返回对应字典项信息。使用如下:
class Person {
/**
* 性别
*/
@DictItem(type = "sex")
private String sex;
}
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 字典解析注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = DictItemSerialize.class)
public @interface DictItem {
/**
* 字典type
*/
String type();
/**
* 字段后缀
*/
String suffix() default "Label";
// /**
// * 颜色字段后缀
// */
// String colorSuffix() default "Color";
}
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.magic.admin.api.entity.SysDictItem;
import com.magic.admin.api.feign.RemoteDictService;
import com.magic.common.core.constant.CacheConstants;
import com.magic.common.core.constant.SecurityConstants;
import com.magic.common.core.util.R;
import com.magic.common.core.util.SpringContextHolder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @date
*/
@NoArgsConstructor
@AllArgsConstructor
public class DictItemSerialize extends JsonSerializer<String> implements ContextualSerializer {
private String type;
private String suffix;
// private String colorSuffix;
@Override
public void serialize(String dictValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(dictValue);
// 如果值不为空,序列化渲染字段值显示的label
if (dictValue != null) {
CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);
Cache cache = cacheManager.getCache(CacheConstants.DICT_DETAILS);
R<List<SysDictItem>> sysDictItemListResult = cache.get(type, R.class);
if(sysDictItemListResult==null) {
RemoteDictService dictService = SpringContextHolder.getBean(RemoteDictService.class);
sysDictItemListResult = dictService.getDictByType(type);
}
if (sysDictItemListResult != null && CollectionUtils.isNotEmpty(sysDictItemListResult.getData())) {
// 序列化字段名称
String fieldName = jsonGenerator.getOutputContext().getCurrentName();
Map<String, SysDictItem> itemValueMap = sysDictItemListResult.getData()
.stream().collect(Collectors.toMap(SysDictItem::getItemValue, Function.identity(), (v1, v2) -> v2));
// 属性存在多个字典值
List<String> dictValueList = Arrays.stream(dictValue.split(",")).collect(Collectors.toList());
StringBuilder label = new StringBuilder();
// String color = null;
for (String sourcesValue : dictValueList) {
SysDictItem sysDictItem = itemValueMap.get(sourcesValue);
if (sysDictItem == null) continue;
if (StrUtil.isBlank(label)) {
label.append(sysDictItem.getLabel());
// color = StrUtil.isBlank(sysDictItem.getDictColor())?"":sysDictItem.getDictColor();
} else {
label.append(",").append(sysDictItem.getLabel());
}
}
jsonGenerator.writeFieldName(fieldName + suffix);
jsonGenerator.writeString(label.toString());
// jsonGenerator.writeFieldName(fieldName + colorSuffix);
// jsonGenerator.writeString(color);
}
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {if (beanProperty != null) {
if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
DictItem dictItem = beanProperty.getAnnotation(DictItem.class);
if (dictItem == null) {
dictItem = beanProperty.getContextAnnotation(DictItem.class);
}
if (dictItem != null) {
return new DictItemSerialize(dictItem.type(), dictItem.suffix());
// return new DictItemSerialize(dictItem.type(), dictItem.suffix(), dictItem.colorSuffix());
}
}
return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
}
return serializerProvider.findNullValueSerializer(null);
}
}
二、多级字典序列化
@DictItem(type = "task_score", level = 2)
private String maxReward;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 字典解析注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = DictItemSerialize.class)
public @interface DictItem {
/**
* 字典type
*/
String type();
/**
* 字典层级
*/
int level() default 1;
/**
* 字段后缀
*/
String suffix() default "Label";
}
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.magic.admin.api.entity.SysDictItem;
import com.magic.admin.api.feign.RemoteDictService;
import com.magic.common.core.constant.CacheConstants;
import com.magic.common.core.constant.SecurityConstants;
import com.magic.common.core.util.R;
import com.magic.common.core.util.SpringContextHolder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @date
*/
@NoArgsConstructor
@AllArgsConstructor
public class DictItemSerialize extends JsonSerializer<String> implements ContextualSerializer {
private String type;
private int level;
private String suffix;
// private String colorSuffix;
@Override
public void serialize(String dictValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(dictValue);
// 如果值不为空,序列化渲染字段值显示的label
if (dictValue != null) {
List<SysDictItem> allSysDictItemList = new ArrayList<>();
List<SysDictItem> sysDictItemList;
RemoteDictService dictService = SpringContextHolder.getBean(RemoteDictService.class);
// 查询第一层
R<List<SysDictItem>> firstLevelSysDictItemListResult = dictService.getByType(type, SecurityConstants.FROM_IN);
if (firstLevelSysDictItemListResult != null && CollectionUtil.isNotEmpty(firstLevelSysDictItemListResult.getData())) {
sysDictItemList = firstLevelSysDictItemListResult.getData();
allSysDictItemList.addAll(sysDictItemList);
for (int i = 1; i < level; i++) {
allSysDictItemList.clear();
if (CollectionUtil.isNotEmpty(sysDictItemList)) {
for (SysDictItem sysDictItem : sysDictItemList) {
R<List<SysDictItem>> itemListResult = dictService.getByType(sysDictItem.getItemValue(), SecurityConstants.FROM_IN);
if (itemListResult != null && CollectionUtil.isNotEmpty(itemListResult.getData())) {
allSysDictItemList.addAll(itemListResult.getData());
}
}
}
sysDictItemList.clear();
sysDictItemList.addAll(allSysDictItemList);
}
}
if (CollectionUtils.isNotEmpty(allSysDictItemList)) {
// 序列化字段名称
String fieldName = jsonGenerator.getOutputContext().getCurrentName();
Map<String, SysDictItem> itemValueMap = allSysDictItemList
.stream().collect(Collectors.toMap(SysDictItem::getItemValue, Function.identity(), (v1, v2) -> v2));
// 属性存在多个字典值
List<String> dictValueList = Arrays.stream(dictValue.split(",")).collect(Collectors.toList());
StringBuilder label = new StringBuilder();
// String color = null;
for (String sourcesValue : dictValueList) {
SysDictItem sysDictItem = itemValueMap.get(sourcesValue);
if (sysDictItem == null) continue;
if (StrUtil.isBlank(label)) {
label.append(sysDictItem.getLabel());
// color = StrUtil.isBlank(sysDictItem.getDictColor())?"":sysDictItem.getDictColor();
} else {
label.append(",").append(sysDictItem.getLabel());
}
}
jsonGenerator.writeFieldName(fieldName + suffix);
jsonGenerator.writeString(label.toString());
// jsonGenerator.writeFieldName(fieldName + colorSuffix);
// jsonGenerator.writeString(color);
}
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
if (beanProperty != null) {
if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
DictItem dictItem = beanProperty.getAnnotation(DictItem.class);
if (dictItem == null) {
dictItem = beanProperty.getContextAnnotation(DictItem.class);
}
if (dictItem != null) {
return new DictItemSerialize(dictItem.type(), dictItem.level(), dictItem.suffix());
// return new DictItemSerialize(dictItem.type(), dictItem.suffix(), dictItem.colorSuffix());
}
}
return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
}
return serializerProvider.findNullValueSerializer(null);
}
}