我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java序列化与字典功能的序列化实例分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java序列化与字典功能的序列化实例分析

这篇文章主要介绍了Java序列化与字典功能的序列化实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java序列化与字典功能的序列化实例分析文章都会有所收获,下面我们一起来看看吧。

两种解决方案

  • 前端查询字典数据然后前端转码

  • 后端查询字典值,然后再转码返回给前段。

本文及时针对方案2 进行的改进

目标:

在需要返回给前段的字段上添加指定的注解例如:@DictDesc 则根据该字段定义的值结合注解配置生成 xxxDesc字段并自动赋值为注解属性值所对应的字典描述;

具体使用的技术涉及到jackson序列化与反序列化,其他JSON工具包也类型的效果;

字典注解定义

@Inherited@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documented@JacksonAnnotationsInside@JsonSerialize(using = DictDescSerializer.class)@JsonDeserialize(using = DictDescDeserializer.class)public @interface DictDesc {        Class<? extends Enum<? extends DictEnum>>[] enumType() default {};        String[] dictType() default {};        String defaultValue() default "";        boolean throwException() default false;}

该注解中定义了解析该注解需要序列化器与返序列化器:

@JsonSerialize(using = DictDescSerializer.class)

@JsonDeserialize(using = DictDescDeserializer.class)

字典序列化与返序列化器的实现

import com.fasterxml.jackson.core.JacksonException;import com.fasterxml.jackson.core.JsonParser;import com.fasterxml.jackson.databind.BeanProperty;import com.fasterxml.jackson.databind.DeserializationContext;import com.fasterxml.jackson.databind.JsonDeserializer;import com.fasterxml.jackson.databind.JsonMappingException;import com.fasterxml.jackson.databind.deser.ContextualDeserializer;import com.aimilin.common.dict.annotation.DictDesc;import com.aimilin.common.dict.service.impl.DictDescSerializerUtils;import lombok.NoArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.BeanUtils;import org.springframework.core.convert.ConversionService;import org.springframework.core.convert.support.DefaultConversionService;import java.beans.PropertyDescriptor;import java.io.IOException;import java.lang.reflect.Method;import java.util.Objects;@Slf4j@NoArgsConstructorpublic class DictDescDeserializer extends JsonDeserializer<Object> implements ContextualDeserializer {        private static final String LABEL_SUFFIX = "Desc";        private Class<?> rawClass;        private ConversionService converter;        private Method writeMethod;        private DictDesc dict;    public DictDescDeserializer(DictDesc dict, BeanProperty property) {        this.dict = dict;        this.rawClass = property.getType().getRawClass();        this.converter = new DefaultConversionService();        Class<?> targetClass = property.getMember().getDeclaringClass();        String writeField = property.getName() + LABEL_SUFFIX;        PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(targetClass, writeField);        this.writeMethod = Objects.isNull(propertyDescriptor) ? null : propertyDescriptor.getWriteMethod();        if (Objects.isNull(this.writeMethod)) {            log.info("类:{},字典属性:{},没有写入方法:{},不设置值!", targetClass.getName(), property.getName(), writeField);        }    }    @Override    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {        DictDesc dict = property.getAnnotation(DictDesc.class);        if (dict != null) {            return new DictDescDeserializer(dict, property);        }        return this;    }    @Override    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {        Object result = this.getValue(p.getText());        this.setDictDesc(result, p.getCurrentName(), p.getCurrentValue());        return result;    }        public Object getValue(String value) throws IOException {        return converter.convert(value, this.rawClass);    }        private void setDictDesc(Object result, String currentName, Object currentValue) {        try {            if (this.writeMethod != null) {                writeMethod.invoke(currentValue, DictDescSerializerUtils.getDesc(this.dict, currentName, result));            }        } catch (Exception e) {            log.error("类:{},字典属性:{},回显异常:{}", currentValue.getClass(), currentName, e.getMessage(), e);        }    }}
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 com.aimilin.common.dict.annotation.DictDesc;import com.aimilin.common.dict.service.impl.DictDescSerializerUtils;import lombok.NoArgsConstructor;import lombok.extern.slf4j.Slf4j;import java.io.IOException;@Slf4j@NoArgsConstructorpublic class DictDescSerializer extends JsonSerializer<Object> implements ContextualSerializer {        private static final String LABEL_SUFFIX = "Desc";        private DictDesc dict;        public DictDescSerializer(DictDesc dict) {        this.dict = dict;    }    @Override    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {        DictDesc dict = property.getAnnotation(DictDesc.class);        if (dict != null) {            return new DictDescSerializer(dict);        }        return this;    }        @Override    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {        provider.defaultSerializeValue(value, gen);        if (dict != null) {            String fieldName = gen.getOutputContext().getCurrentName();            // 添加转换之后的字段:xxxDesc            gen.writeStringField(fieldName.concat(LABEL_SUFFIX), DictDescSerializerUtils.getDesc(dict, fieldName, value));        }    }}

字典序列化与反序列工具类

import cn.hutool.extra.spring.SpringUtil;import com.aimilin.common.core.pojo.system.SysDict;import com.aimilin.common.dict.annotation.DictDesc;import com.aimilin.common.dict.annotation.DictEnum;import com.aimilin.common.dict.exception.DictException;import com.aimilin.common.dict.exception.enums.DictExceptionEnum;import com.aimilin.common.dict.service.SysDictService;import lombok.extern.slf4j.Slf4j;import org.apache.commons.collections4.CollectionUtils;import org.apache.commons.lang3.ArrayUtils;import org.apache.commons.lang3.StringUtils;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Arrays;import java.util.List;import java.util.Objects;@Slf4jpublic class DictDescSerializerUtils {        public static String getDesc(DictDesc dict, String field, Object value) {        if (ArrayUtils.isEmpty(dict.dictType()) && ArrayUtils.isEmpty(dict.enumType())) {            throw new DictException(DictExceptionEnum.REQUEST_DICT_TYPE, field);        }        try {            if (value == null) {                throw new DictException(DictExceptionEnum.REQUEST_NOT_NULL, field);            }            if (ArrayUtils.isNotEmpty(dict.enumType())) {                return getEnumDesc(dict, field, value);            }            return getDictDesc(dict, field, value);        } catch (Exception e) {            log.error("字典转换异常, field:{}, enumType:{}, dictType:{}, 值:{}, 异常:{}",                    field, dict.enumType(), dict.dictType(), value, e.getMessage(), e);            if (dict.throwException()) {                throw e instanceof DictException ? (DictException) e : new DictException(DictExceptionEnum.DICT_EXCEPTION, e);            }            return dict.defaultValue();        }    }        public static String getEnumDesc(DictDesc dict, String field, Object value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {        for (Class<? extends Enum<? extends DictEnum>> dictEnum : dict.enumType()) {            Method getCode = dictEnum.getMethod("getCode");            Method getMessage = dictEnum.getMethod("getMessage");            for (Enum<? extends DictEnum> e : dictEnum.getEnumConstants()) {                if (value.equals(getCode.invoke(e))) {                    return Objects.toString(getMessage.invoke(e));                }            }        }        throw new DictException(DictExceptionEnum.UNKNOWN_ENUM_DICT_VALUE,                String.format("Field:%s, EnumType: %s, Value: %s", field, Arrays.toString(dict.enumType()), value));    }        public static String getDictDesc(DictDesc dict, String field, Object value) {        if (ArrayUtils.isEmpty(dict.dictType())) {            throw new DictException(DictExceptionEnum.REQUEST_DICT_TYPE, field);        }        List<SysDict> sysDictList = SpringUtil.getBean(SysDictService.class).getDictByDictTypeCode(dict.dictType());        if (CollectionUtils.isEmpty(sysDictList)) {            throw new DictException(DictExceptionEnum.NO_DICT_DATA, field, Arrays.toString(dict.dictType()));        }        for (SysDict sysDict : sysDictList) {            if (StringUtils.equals(sysDict.getCode(), Objects.toString(value))) {                return sysDict.getValue();            }        }        throw new DictException(DictExceptionEnum.UNKNOWN_DICT_VALUE, field, Arrays.toString(dict.dictType()));    }}

字典转换服务类

public interface SysDictService {        public List<SysDict> getDictByDictTypeCode(String... dictTypeCodes);}

服务实现类:

@Servicepublic class SysDictServiceImpl implements SysDictService {    @Resource    private SystemContextServiceApi systemContextServiceApi;    @Resource    private SysDictCache sysDictCache;        @Override    public List<SysDict> getDictByDictTypeCode(String... dictTypeCodes) {        List<SysDict> dictTypeCache = sysDictCache.getDictTypeCache(dictTypeCodes);        if (CollectionUtils.isNotEmpty(dictTypeCache)) {            return dictTypeCache;        }        return systemContextServiceApi.getDictByDictTypeCode(dictTypeCodes).getData();    }}

字典缓存服务

可以修改为使用本地缓存方式

@Slf4j@Servicepublic class SysDictCache {    @Resource    private RedisService redisService;        public List<SysDict> getDictTypeCache(String... dictTypes) {        if (Objects.isNull(redisService)) {            log.info("redisService 为空,不使用字典缓存");            return null;        }        List<List<SysDict>> dictValues = redisService.getMultiCacheMapValue(CommonConstant.DICT_CACHE_KEY, Arrays.asList(dictTypes));        if (CollectionUtils.isEmpty(dictValues)) {            return null;        }        List<SysDict> result = new ArrayList<>();        dictValues.stream().filter(Objects::nonNull).forEach(result::addAll);        log.debug("查询字典缓存,dictTypes:{}, 结果:{}", dictTypes, result);        return result;    }        public void cleanDictTypeCache(String... dictTypes) {        if (Objects.isNull(redisService)) {            return;        }        redisService.deleteCacheMapValue(CommonConstant.DICT_CACHE_KEY, dictTypes);        log.info("清除字典缓存,dictTypes:{}", StringUtils.join(dictTypes));    }        public void putDictTypeCache(List<SysDict> sysDictList) {        if (Objects.isNull(redisService) || CollectionUtils.isEmpty(sysDictList)) {            return;        }        Map<String, List<SysDict>> collect = sysDictList.stream().collect(Collectors.groupingBy(SysDict::getTypeCode));        for (Map.Entry<String, List<SysDict>> entry : collect.entrySet()) {            redisService.setCacheMapValue(CommonConstant.DICT_CACHE_KEY, entry.getKey(), entry.getValue());            log.info("设置字典缓存,dictType:{},结果:{}", entry.getKey(), entry.getValue());        }    }}

关于“Java序列化与字典功能的序列化实例分析”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Java序列化与字典功能的序列化实例分析”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java序列化与字典功能的序列化实例分析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java序列化与字典功能的序列化实例分析

这篇文章主要介绍了Java序列化与字典功能的序列化实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java序列化与字典功能的序列化实例分析文章都会有所收获,下面我们一起来看看吧。两种解决方案前端查询字典数
2023-07-02

Java中序列化与反序列化的示例分析

这篇文章将为大家详细讲解有关Java中序列化与反序列化的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、前言序列化:将对象转换为二进制序列在网络中传输或保存到磁盘反序列化:从网络或磁盘中将二进制
2023-06-15

Java序列化和反序列化示例分析

这期内容当中小编将会给大家带来有关Java序列化和反序列化示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。序列化是为了把Java对象转化为字节序列(字节流)的过程。然后深拷贝是通过对流的操作来实现的
2023-06-26

Python中序列化与反序列化的示例分析

这篇文章将为大家详细讲解有关Python中序列化与反序列化的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。初识序列化与反序列化什么是序列化?通俗一点来说,序列化就是将 对象的信息 或者 数据结构的
2023-06-29

Java对象的XML序列化与反序列化实例解析

上一篇文章我们介绍了java实现的各种排序算法代码示例,本文我们看看Java对象的xml序列化与反序列化的相关内容,具体如下。XML是一种标准的数据交换规范,可以方便地用于在应用之间交换各类数据。如果能在Java对象和XML文档之间建立某种
2023-05-30

java原生序列化和Kryo序列化性能实例对比分析

简介最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括:专门针对Java语言的:Kryo,FST等等跨语言的:Protostuff,ProtoBuf,Thrift,Avro,MsgPack等等这些序列化方式的性
2023-05-31

Python的pickle序列化和JSON序列化实例分析

本文小编为大家详细介绍“Python的pickle序列化和JSON序列化实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python的pickle序列化和JSON序列化实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一
2023-06-30

Ezpop pop序列化链反序列化实例分析

这篇文章主要介绍了Ezpop pop序列化链反序列化实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Ezpop pop序列化链反序列化实例分析文章都会有所收获,下面我们一起来看看吧。
2023-06-30

Java对象的序列化和反序列化举例分析

本篇内容介绍了“Java对象的序列化和反序列化举例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、什么是序列化与反序列化?  序列化:
2023-06-19

深入浅析Java中的序列化与反序列化

这篇文章将为大家详细讲解有关深入浅析Java中的序列化与反序列化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java 序列化和反序列化实例详解在分布式应用中,对象只有经过序列化才能在各个分
2023-05-31

Java序列化和克隆的实例分析

Java序列化和克隆的实例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。序列化Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从
2023-06-17

Java的序列化与反序列化怎么实现

本篇内容介绍了“Java的序列化与反序列化怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java对象的序列化Java平台允许我们在内
2023-07-04

json序列化的示例分析

这篇文章主要为大家展示了“json序列化的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“json序列化的示例分析”这篇文章吧。json序列化(javaBean转Json的细节)Java对
2023-06-29

java安全fastjson1.2.24反序列化TemplatesImpl实例分析

这篇文章主要介绍“java安全fastjson1.2.24反序列化TemplatesImpl实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java安全fastjson1.2.24反序列化Te
2023-07-02

Java的序列化库性能测试分析

这篇文章主要讲解了“Java的序列化库性能测试分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java的序列化库性能测试分析”吧! 本次测试专注于 cyclefree 数据结构的编码和解码
2023-06-17

Java Socket通信的序列化和反序列化的实例介绍

本篇内容介绍了“Java Socket通信的序列化和反序列化的实例介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java Socket通
2023-06-17

Python反序列化的示例分析

这篇文章给大家分享的是有关Python反序列化的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Python反序列化漏洞Pickle序列化:pickle.dumps() 将对象序列化为字符串、pickle.
2023-06-29

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录