spring序列化

介绍

Spring中从JSON到JSON的序列化/反序列化已广泛用于基于Spring的现代应用程序中。 它基于杰克逊。 Jackson可以轻松地将任何POJO序列化为JSON,反之亦然。 这段代码写得很好。 我从来没有遇到任何问题。 涉及自定义序列化程序时,将变得更加困难。 这篇文章展示了如何在带有自动装配字段的Spring中使用自定义序列化程序。

定义自定义序列化器

通常,一个类的自定义序列化器是从继承的
com.fasterxml.jackson.databind.ser.std.StdSerializer。 此类定义了一些构造函数,但是框架只需要一个无参数的构造函数即可调用超类,如下所示:

public CustomSerializer() {this(null);
}public CustomSerializer(Class<ObjectToSerialize> t) {super(t);
}

然后是实际编写JSON必须实现的主要方法:

@Override
public void serialize(ObjectToSerialize value, JsonGenerator gen, SerializerProvider provider) throws IOException {gen.writeStartObject();...provider.defaultSerializeField("some field", value.getField(), gen);...gen.writeEndObject();
}

创建序列化程序类时,必须将其注册为ObjectToSerialize的序列化程序。 这可以通过在类上使用@JsonSerialize注释来完成:

@JsonSerialize(using = CustomSerializer.class)
public class ObjectToSerialize {

现在,杰克逊将对该类的所有实例使用此自定义序列化程序。 如有必要,可以通过子类编写自定义解串器
com.fasterxml.jackson.databind.deser.std.StdDeserializer <T>

循环引用和@JsonIdentityInfo

对于大多数使用Spring和Hibernate的商业应用程序,循环引用的问题迟早会出现。 这是一个简单的例子。

我们有2个课程:

public class Building {@Id@GeneratedValue(<parameters>)private Long id;private Set<Apartment> apartments;
}public class Apartment {@Id@GeneratedValue(<parameters>)private Long id;private Building building;
}

如果我们尝试序列化至少有一个公寓的建筑物,则会得到StackOverflowException。

杰克逊有一个解决此问题的方法-@JsonIdentityInfo。

如果将注释@JsonIdentityInfo添加到此类,则:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ObjectToSerialize {

那么任何ObjectMapper都将通过用其ID替换除第一个对象以外的所有对象的出现而打破循环。 像这样:

{"id": 1,"apartments": [{"id": 2,"building": 1 - the object is replaced with its ID},{"id": 3,"building": 1 - the object is replaced with its ID}]
}

这些是Jackson提供的用于自定义序列化和处理循环引用的工具。

JSON结构问题

问题

@JsonIdentityInfo适用于简单的应用程序。 但是随着应用程序以默认格式增长,它可能会影响JSON的结构。 例如,如果某些方法在一个响应中返回建筑物和区域,则可能会发生以下情况:

{"buildings": [{"id": 1,"apartments": [{"id": 2,"building": 1 - the object is replaced with its ID},{"id": 3,"building": 1 - the object is replaced with its ID}]}],"districts": [{"buildings": [{"id": 5,...},1, - the object is replaced with its ID{"id": 6,...}]}]
}

从解析器的角度来看,这种替换可能是完全不可预测的。 在数组中,它可能会遇到对象和ID。 这可能发生在任何字段和任何对象上。 如果序列化提供程序多次找到该对象,则使用@JsonIdentityInfo对该类进行注释的任何对象都将替换为其ID。 序列化提供程序发现的具有相同ID的每个第二,第三,第四等实例都将替换为其ID。

这里的解决方案是使用单独的ObjectMapper编写JSON的一部分。 已经看到的ID的列表存储在由ObjectMapper创建的序列化提供程序中。 通过创建单独的ObjectMapper(具有可能不同的配置),可以重置列表。

对于返回不同对象类型的“复合” JSON结果,可以编写自定义序列化程序。 在此自定义序列化程序中,“标头”是使用JsonGenerator方法手动编写的,当达到JSON中的正确级别时,我们将创建一个新的ObjectMapper并编写外观更好的JSON。

{"buildings": [ - create a new ObjectMapper{"id": 1,"apartments": [{"id": 2,"building": 1 - the object is replaced with its ID},{"id": 3,"building": 1 - the object is replaced with its ID}]}],"districts": [ - create a new ObjectMapper{"buildings": [{"id": 5,...},{ - the object is written as a JSON Object not an ID"id": 1,...},{"id": 6,...}]}]
}

要将JSON写入原始生成器,我们可以使用
ObjectMapper.writeValueAsString和
JsonGenerator.writeRawValue(String)。

PS也可以通过以下方式创建新的序列化提供程序
DefaultSerializerProvider.createInstance(SerializationConfig,SerializerFactory),但它可能更复杂。

自定义序列化器自动装配问题

问题

我们希望能够在自定义序列化程序中使用@Autowire。 这是Spring的最佳功能之一! 实际上,如果使用默认的ObjectMapper,它就可以工作。 但是,如果我们使用JSON结构问题的解决方案,则该解决方案不适用于由我们自己的对象映射器实例化的自定义序列化程序。

我们自己的对象映射器必须配置有特殊的HandlerInstantiator:

// try to use the default configuration as much as possible
ObjectMapper om = Jackson2ObjectMapperBuilder.json().build();
// This instantiator will handle autowiring properties into the custom serializers
om.setHandlerInstantiator(
new SpringHandlerInstantiator(this.applicationContext.getAutowireCapableBeanFactory()));

如果自定义对象映射器是在另一个由默认ObjectMapper创建的自定义序列化器中创建的,则它可以自动装配ApplicationContext。

翻译自: https://www.javacodegeeks.com/2019/01/spring-custom-serializers-jsonidentityinfo.html

spring序列化

spring序列化_使用@JsonIdentityInfo的Spring自定义序列化器相关推荐

  1. spring安全性_具有PreAuthorize的Spring方法安全性

    spring安全性 朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 数分钟之内即可在任何应用程序中对用户进行身份验证,管理和保护. 本教程将探讨使 ...

  2. spring 全局变量_精华:关于Spring的15点总结

    1.Spring 中 AOP 的应用场景.Aop 原理.好处? 答:AOP 用来封装横切关注点,具体可以在下面的 场景中使用: Authentication 权限.Caching缓存.Contextp ...

  3. java rest 序列化_一文看懂Java序列化

    一文看懂Java序列化 简介 首先我们看一下wiki上面对于序列化的解释. 序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓 ...

  4. java spring异常处理_【异常处理】Spring项目异常如何做异常处理

    类似SpringMVC项目的异常处理可以这样做: 整个项目创建全局的: 1.一个自定义异常如OneException和错误码,统一封装所有异常. 2.一个返回实体类ResponseEntity,包含返 ...

  5. sts4创建spring项目_使用STS 创建spring配置文件

    PHP_环境配置_python脚本_2017 Apache配置 需要安装:VC2015 httpd-2.4.16-win32-VC14.zip VC14就是2015的环境. 又比如:php-5.6.1 ...

  6. java文件序列化_通过快速Java和文件序列化加快速度

    java文件序列化 从Java的第一个版本开始,许多开发人员每天都在努力实现至少与C / C ++一样好的性能. JVM供应商正在通过实现一些新的JIT算法来尽力而为,但仍有许多工作要做,尤其是在我们 ...

  7. java timer 序列化_编程达人 应用层timer_如何序列化timer

    本文摘自    https://www.cnblogs.com/embedded-linux/p/9093990.html 应用层使用timer可以启动多个timer(每个timer管理一个目标时间) ...

  8. java基础巩固-宇宙第一AiYWM:为了维持生计,Spring全家桶_Part1-3(学学Spring源码呗:默认的标签和自定义标签是咋解析的)~整起

    Part3:上一次说到了Spring的DefaultBeanDefinitionDocumentReader类中的parseBeanDefinitions(Element root, BeanDefi ...

  9. 使用@JsonIdentityInfo的Spring自定义序列化器

    介绍 Spring中从JSON到JSON的序列化/反序列化已广泛用于基于Spring的现代应用程序中. 它基于杰克逊. Jackson可以轻松地将任何POJO序列化为JSON,反之亦然. 这段代码写得 ...

最新文章

  1. 服务器运行码用户名a多少呢,如何以非根用户身份运行gunicorn/a python应用服务器?...
  2. badboy页面脚本发生错误,解决方案
  3. 静态网页使用Node.js跨域代理服务
  4. 亿级Web系统搭建――单机到分布式集群 转载
  5. 央行放水点燃房价,普通家庭如何理财?
  6. boost::spirit::karma::real_generator相关的测试程序
  7. php利用openssl实现RSA非对称加密签名
  8. Shiro切入Spring的方式
  9. 关于Vmware workstation虚拟机的网络设置问题
  10. 工业局的云计算机,广州市海珠区科技工业商务和信息化局方奕涛局长带队二次调研云算...
  11. 如何使用单例EJB,Ehcache和MBean构建和清除参考数据缓存
  12. 2017-4-20实体类,数据访问类.字符串攻击.防攻击
  13. Unity基础知识结构总结
  14. prince2 成功的项目管理_我的PRINCE2故事
  15. 深度学习的黑魔法防御术:恶意样本(Adversarial Example) 的防御策略综述
  16. CodeFroces gym 100781 A.Adjoin the Networks(贪心)
  17. Win10专业版错误代码0xc0000225在吗修复?
  18. charles https 抓包
  19. 破解XP系统密码的常用的几种方法
  20. 爬虫Scrapy框架运用----房天下二手房数据采集

热门文章

  1. D - Covering HDU - 6185(未解决完)
  2. P6242-[模板]线段树3【吉司机线段树】
  3. CF5E-Bindian Signalizing【单调栈】
  4. P4716-[模板]最小树形图
  5. jzoj6805-NOIP2020.9.26模拟speike【扫描线】
  6. P3914-染色计数【树形dp】
  7. 欢乐纪中B组周五模拟赛【2019.3.8】
  8. 2725. [Violet 6]故乡的梦(删边最短路同[TJOI2012]桥)
  9. 1.数据湖deltalake初识
  10. 关于HashMap容量的初始化,还有这么多学问