【Spring Boot丨序列化、反序列化】

news2024/9/23 20:36:28

序列化、反序列化

  • 概述
  • Jackson 序列化和反序列化
    • 简介
    • 自定义序列化器
      • 注册外部序列化程序:
    • 指定类的 Json 序列化、反序列化

在这里插入图片描述

主页传送门:📀 传送

概述


  序列化是将对象转换为字节序列的过程,而反序列化则是将字节序列恢复为对象的过程。在Java中,序列化和反序

列化是通过实现Serializable接口来实现的。当一个类实现了Serializable接口时,它的对象就可以被序列化和反序列化了 。

序列化最重要的作用是在传递和保存对象时保证对象的完整性和可传递性

Jackson 序列化和反序列化


简介

  如果您使用 Jackson 来序列化和反序列化 JSON 数据,您可能需要编写自己的JsonSerializerJsonDeserializer类。自定义序列化器通常通过 module 向 Jackson 注册。

自定义序列化器

俩种实现方法:

  • 使要序列化的值、类实现接口org.codehaus.jackson.map.JsonSerializedWithType :这与实现java.lang.Serialized类似,调用值类的serialize()方法 来处理序列化。
    • 注意:在 Jackson 1.5之前,推荐的接口是org.codehaus.jackson.map.JsonSerialized ;但现在已废弃,因为它不支持处理可能的附加类型信息(有关详细信息,请参阅JacksonPolymorphicDeserialization)。
    • 如果选择使用此方法,请考虑从部分实现开始,例如org.codehaus.jackson.map.ser.SerializerBase(适用于任何类型)或org.codehaus.jackson.map.ser.ScalarSerializerBase(适用于输出JSON字符串、布尔值或数字的序列化程序,也称为标量类型)
  • 实现org.codehaus.jackson.map.JsonSerializer来创建一个外部序列化器,该程序可以注册以处理某些类型的值(或者更具体地说,某些属性的值)

注册外部序列化程序:

  • 使用注释

  • 类和方法可以使用@JsonSerialize.using(将序列化程序类作为参数)进行注释,以指示要使用的序列化程序的类型

使用Jackson 1.7及以上版本

  Jackson 1.7添加了通过Module 接口注册序列化器和反序列化的能力。这是添加自定义序列化程序的推荐方法——所有序列化程序都被视为“通用”,因为除非找到更具体的绑定,否则它们都用于子类型。

示例:

 ObjectMapper mapper = new ObjectMapper();
 SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
 testModule.addSerializer(new MyCustomSerializer()); // 假设序列化程序声明了要绑定到的正确类
 mapper.registerModule(testModule);

  为了更高级地处理序列化程序的类型,您可能需要直接实现Module接口;这将提供对精确匹配逻辑的更多控制。在处理泛型类型(尤其是映射和集合)时,这可能是必要的。

Jackson 1.7之前

主要方法:

  • 通过使用自定义序列化程序工厂(org.codehaus.jackson.map.SerizerFactory)

    • 使用或扩展现有的实现,org.codehaus.ackson.map.ser.CustomSerializerFactory(如果不适用,甚至从头开始实现)

    • 通过调用addSpecificMappingaddGenericMapping添加映射(从序列化的Class到JsonSerializer实例)

    • 自定义序列化程序工厂需要向ObjectMapper.setSerializerFactory注册才能由ObjectMapper使用

请注意,从1.8开始,CustomSerializerFactory 已被弃用,不应使用。

示例:


// Configuration of ObjectMapper:
{
   // First: need a custom serializer provider
   StdSerializerProvider sp = new StdSerializerProvider();
   sp.setNullValueSerializer(new NullSerializer());
   // And then configure mapper to use it
   ObjectMapper m = new ObjectMapper();
   m.setSerializerProvider(sp);
   // Serialization as done using regular ObjectMapper.writeValue()
}

// and NullSerializer can be something as simple as:
public class NullSerializer extends JsonSerializer<Object>
{
   public void serialize(Object value, JsonGenerator jgen,
SerializerProvider provider)
       throws IOException, JsonProcessingException
   {
       // any JSON value you want...
       jgen.writeString("");
   }
}

指定类的 Json 序列化、反序列化


   Spring Boot 提供了另一种 @JsonComponent 注释,可以更容易地直接注册 Spring Beans。
可以直接在 JsonSerializer JsonDeserializer 实现上使用@JsonComponent注释。您还可以在包含序列化程序/反序列化程序作为内部类的类上使用它

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import org.springframework.boot.jackson.JsonComponent;

@JsonComponent
public class MyJsonComponent {

    public static class Serializer extends JsonSerializer<MyObject> {

        @Override
        public void serialize(MyObject value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
            jgen.writeStartObject();
            jgen.writeStringField("name", value.getName());
            jgen.writeNumberField("age", value.getAge());
            jgen.writeEndObject();
        }

    }

    public static class Deserializer extends JsonDeserializer<MyObject> {

        @Override
        public MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
            ObjectCodec codec = jsonParser.getCodec();
            JsonNode tree = codec.readTree(jsonParser);
            String name = tree.get("name").textValue();
            int age = tree.get("age").intValue();
            return new MyObject(name, age);
        }

    }

}


ApplicationContext 中的所有 @JsonComponent bean 都会自动注册到 Jackson。因为 @JsonComponent 是使用 @Component 进行元注释的,所以通常的组件扫描规则适用。

Spring Boot 还提供了 JsonObjectSerializer JsonObjectDeserializer 基类,它们在序列化对象时提供了标准 Jackson 版本的有用替代方法。有关详细信息,请参阅 Javadoc 中的 JsonObjectSerializer 和 JsonObjectDeserializer 。

在这里插入图片描述

  如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏  🙌一起讨论
  你的支持就是我✍️创作的动力!					  💞💞💞

序列化反序列化测试用例及替换默认Jackson库源码:
序列化、反序列化测试

参考资料
Spring Boot json官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/806431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用于系统监控及进程管理python库之psutil

前言 对于一个job级别应用再进行测试的过程中&#xff0c;不可避免测试该服务的一些性能&#xff0c;比如占有cpu的使用量&#xff0c;使用的memory的大小等&#xff0c;比较简单的方式是在服务中起一个并行的线程&#xff0c;每隔一段时间打印这些关注量的大小&#xff0c;之后…

【二分答案】CF1661 C

Problem - C - Codeforces 题意&#xff1a; 思路&#xff1a; 在check的时候&#xff0c;我们要尽量用算贡献的思想&#xff0c;并且大胆贪心 Code&#xff1a; #include <bits/stdc.h>#define int long longusing namespace std;const int mxn3e510; const int mxe3…

MySQL基础扎实——列对比运算符是什么

词义解释 在MySQL中&#xff0c;用于进行列对比的运算符主要有以下几种&#xff0c;其实就是逻辑运算符号&#xff1a; 等号&#xff08;&#xff09;&#xff1a;用于判断两个列是否相等&#xff0c;例如&#xff1a;column_name value。 不等号&#xff08;<>或!&am…

Verilog语法学习——边沿检测

边沿检测 代码 module edge_detection_p(input sys_clk,input sys_rst_n,input signal_in,output edge_detected );//存储上一个时钟周期的输入信号reg signal_in_prev;always (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)signal_in_prev < 0;else…

95. Python基础教程:异常处理try...except语句

【目录】 文章目录 1. try...except语法解析2. 程序异常3. except的4种使用方式3.1 单独的except3.2 except 异常名称3.3 except 异常类型 as 别名3.4 except (异常类型1,异常类型2) as 别名 4. 总结 【正文】 1. try…except语法解析 try[traɪ]&#xff1a;尝试。 except[…

【QT】Day4

1> 思维导图 2> 手动完成服务器的实现&#xff0c;并具体程序要注释清楚 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器类 #include <QTcpSocket> //客户端类 #include <QMessageBox> //…

综合能源系统(4)——综合能源系统建模方法

综合能源系统关键技术与典型案例  何泽家&#xff0c;李德智主编 本文主要从物理、信息、价值三个方面介绍综合能源系统关键技术&#xff0c;如图3-1所示。 物理方面&#xff1a;主要包括综合能源系统建模分析技术、规划设计(配置)技术、优化控制技术、运行维护技术和综合评…

mybatisPlus之逻辑删除解读

目录 为什么会有逻辑删除 逻辑删除基本介绍 逻辑删除的使用 局部使用 全局使用 为什么会有逻辑删除 在我们对数据进行增删查改的时候&#xff0c;对于删除操作来说&#xff0c;我们思考一个问题&#xff0c;在实际开发中我们真的会将数据完成从数据库中删除掉么&#xff1f…

二叉搜索树(二叉排序树)

文章目录 基本概念基本操作实现分析插入数据查找数据删除数据遍历数据 源码 基本概念 二叉搜索树也叫搜索二叉树、二叉排序树、排序二叉树。是一种对查找和排序都有用的特殊二叉树。 二叉搜索树&#xff08;Binary Search Tree&#xff0c;简称BST&#xff09; 如何构建一颗二叉…

【使用维纳滤波进行信号分离】基于维纳-霍普夫方程的信号分离或去噪维纳滤波器估计(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【Windows】WDS中如何跳过语言选择以及身份验证

WDS&#xff08;Windows Deployment Services&#xff09;是微软的一项网络服务&#xff0c;用于快速和方便地部署Windows操作系统到多台计算机上。它提供了一种自动化的方式来安装、配置和管理操作系统映像&#xff0c;使企业能够快速部署和更新大量的计算机系统。网上有很多W…

二叉搜索树的本质

引言 打算写写树形数据结构&#xff1a;二叉查找树、红黑树、跳表和 B 树。这些数据结构都是为了解决同一个基本问题&#xff1a;如何快速地对一个大集合执行增删改查。 本篇是第一篇&#xff0c;讲讲搜索树的基础&#xff1a;二叉搜索树。 基本问题 如何在一千万个手机号中…

设计模式-中介者模式在Java中使用示例-客户信息管理

场景 欲开发客户信息管理窗口界面&#xff0c;界面组件之间存在较为复杂的交互关系&#xff1a;如果删除一个客户&#xff0c; 要在客户列表(List)中删掉对应的项&#xff0c;客户选择组合框(ComboBox)中客户名称也将减少一个&#xff1b; 如果增加一个客户信息&#xff0c;…

SpringBoot2.7集成Swagger3.0和knife4j实现API接口文档开发

1. 概述 Swagger 3 是一个用于描述、构建和测试 RESTful Web 服务的开源工具集。它提供了一种简单而强大的方式来定义和文档化 API 接口&#xff0c;同时还具备自动生成客户端代码和服务器存根代码的功能。 Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案&#xff…

DNSPod十问秦勇:为什么医疗AI最爱眼科?

本期嘉宾 秦勇 鹰瞳科技Airdoc COO 秦勇&#xff0c;鹰瞳科技&#xff08;Airdoc&#xff09;COO&#xff0c;中国人工智能学会智慧医疗专委会委员&#xff0c;长期从事医疗人工智能方向的工作&#xff0c;拥有丰厚的项目经验、管理经验和技术积累&#xff0c;参与多个医院人…

掌握Python的X篇_13+14_Python条件语句实例:判断闰年、成绩评定

前面学习了条件语句以及调试的基本技巧&#xff0c;本篇介绍两个与条件语句有关的实例&#xff0c;对前面的知识又深刻认识。 文章目录 1. 判断闰年1.1 版本11.2 版本21.3 一行代码太长的处理方法 2. 根据成绩评级 1. 判断闰年 用户输入年份&#xff0c;判断该年份是否为闰年…

基于springboot+jpa+mysql+html网上中药商城系统

基于springbootjpamysqlhtml网上中药商城系统 一、系统介绍二、功能展示1.主页(客户)2.登陆&#xff08;客户&#xff09;3.注册&#xff08;客户&#xff09;4.购物车(客户)5.我的订单&#xff08;客户&#xff09;6.用户管理&#xff08;管理员&#xff09;7.分类管理&#x…

基于鲸鱼优化算法的5G信道估计(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…

1400*D. Divide by three, multiply by two

题意&#xff1a; 一个序列&#xff0c;每个数都是前一个数乘2或者除3&#xff0c;打乱之后&#xff0c;需要你排出原来的序列。 queue和deque模拟 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N1e55; ll n,a[N]; queue<ll>q; d…

Python进行数据分析(详细教程)

1.为什么选择Python进行数据分析&#xff1f; Python是一门动态的、面向对象的脚本语言&#xff0c;同时也是一门简约&#xff0c;通俗易懂的编程语言。Python入门简单&#xff0c;代码可读性强&#xff0c;一段好的Python代码&#xff0c;阅读起来像是在读一篇外语文章。Pyth…