java 自定义字典序列化器

一、字典序列化器

实现自定义字典序列化注解,在对象进行序列化时,加载指定字典类型,并根据属性值匹配对应的字典项,返回对应字典项信息。使用如下:

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);
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whitemeen太白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值