springboot 序列化/反序列化
2026/7/15 12:52:46 网站建设 项目流程

对于我们新手来说,似乎按照对应的规则配置, 就能接受返回参数, controller层上得到或返回一个对象; 其实内部有个序列化/反序列化操作,上文实体类的注解就需要我们理解一下这些逻辑了

为什么必须序列化/反序列化?

HTTP 协议传输的数据本质上是文本(字符串),它不认识 Java 对象或 JavaScript 对象。所以对象在传输前必须转换成字符串,接收方再把字符串还原成对象。

后端Java对象 ──[序列化]──→JSON字符串 ──[HTTP传输]──→JSON字符串 ──[反序列化]──→ 前端JS对象 前端JS对象 ──[序列化]──→JSON字符串 ──[HTTP传输]──→JSON字符串 ──[反序列化]──→ 后端Java对象

后端 → 前端

// 后端:Java 对象Orderorder=newOrder();order.setId(1L);order.setCreateTime(LocalDateTime.now());// 序列化:Java 对象 → JSON 字符串// {"id":1,"createTime":"2026-07-15 10:50:00"}returnorder;// Spring 自动通过 Jackson/FastJSON 序列化后返回
// 前端:收到 JSON 字符串,自动反序列化为 JS 对象fetch('/order/1').then(res=>res.json()).then(data=>{console.log(data.id);// 1console.log(data.createTime);// "2026-07-15 10:50:00"});

前端 → 后端

// 前端:JS 对象constorder={id:1,createTime:"2026-07-15 10:50:00"};// 序列化:JS 对象 → JSON 字符串,通过 HTTP 发送fetch('/order',{method:'POST',headers:{'Content-Type': 'application/json'},body:JSON.stringify(order)// 手动或框架自动序列化});
// 后端:收到 JSON 字符串,反序列化为 Java 对象@PostMapping("/order")publicvoidcreateOrder(@RequestBodyOrderorder){// Spring 自动反序列化System.out.println(order.getId());// 1System.out.println(order.getCreateTime());// LocalDateTime 对象}
传输内容是否需要序列化说明
对象/复杂数据结构✅ 必须转成 JSON 字符串传输
简单类型(String、Number)可以看作隐式序列化本质也是转成字符串
文件(二进制)✅ 但方式不同通常用multipart/form-data,不是 JSON 序列化
URL 参数(?id=1&name=xxx)✅ 但方式不同用 URL 编码,不是 JSON 序列化

这也是为什么前面讨论的 @JsonFormat、@JSONField、@DateTimeFormat 这些注解如此重要——它们就是在控制序列化和反序列化过程中日期字段的格式。

规则

JSON 序列化框架(FastJSON、Jackson)的默认规则是:
序列化:把对象中所有非静态、非瞬态的字段(或有 getter 的属性)转成 JSON 键值对
反序列化:把 JSON 中的键值对,按字段名匹配,自动赋值给对象的对应属性(通过 setter 或直接字段访问)

@DatapublicclassOrder{privateLongid;privateStringname;privateIntegerrelatedFundProjectCount;// 普通属性,什么都没加}
// 序列化:Java → JSONOrderorder=newOrder();order.setId(1L);order.setName("测试订单");order.setRelatedFundProjectCount(5);Stringjson=JSON.toJSONString(order);// 输出:{"id":1,"name":"测试订单","relatedFundProjectCount":5} ✅ 正常// 反序列化:JSON → JavaStringjsonInput="{\"id\":2,\"name":"另一个订单","relatedFundProjectCount":10}";Orderorder2=JSON.parseObject(jsonInput,Order.class);System.out.println(order2.getRelatedFundProjectCount());// 10 ✅ 正常

类的转换

实体类里, 以下常见类型都不需要加任何注解,框架内置了转换器:

类型示例
基本类型及包装类IntegerLongBooleanDouble
字符串String
集合ListSetMap
数组String[]Integer[]
嵌套对象UserOrderItem等自定义类

只有框架不知道该怎么转的类型,才需要加注解或自定义转换器:

类型问题解决方案
Date/LocalDateTime格式不统一@JSONField(format = ...)
LocalDate格式不统一@JSONField(format = ...)
枚举默认输出序号或名称,可能不符合需求@JSONField或自定义序列化器
特殊对象(如BigDecimal需要指定精度)默认行为不满足自定义序列化器

普通属性(Integer、String、Long 等)什么都不加,序列化和反序列化都能正常工作。
加注解(如 @JSONField)只是用来覆盖默认行为,比如改格式、改字段名、忽略字段等。不需要特殊处理时,就不用加。

Jackson(Spring Boot 默认)

为什么要写@Data
除了在代码里 使用set, get方法, 用这个注解的还有个重要作用就是 Spring Boot 默认Jackson默认的字段可见性策略是

  • 序列化:找 public 的 getter 方法 或 public 的字段
  • 反序列化:找 public 的 setter 方法 或 public 的字段

所以,不写 getter/setter 也能序列化/反序列化,只是 Jackson 默认配置下不行,需要额外配置。而 FastJSON 和 Lombok 方案天然支持。

JSON.toJSONString, JSON.parseObject

有时候 数据库存了一个json类型的字符串, 用的就是上的方法

// 序列化:Java → JSONOrderorder=newOrder();order.setId(1L);order.setName("测试订单");order.setRelatedFundProjectCount(5);Stringjson=JSON.toJSONString(order);// 输出:{"id":1,"name":"测试订单","relatedFundProjectCount":5} ✅ 正常// 反序列化:JSON → JavaStringjsonInput="{\"id\":2,\"name":"另一个订单","relatedFundProjectCount":10}";Orderorder2=JSON.parseObject(jsonInput,Order.class);System.out.println(order2.getRelatedFundProjectCount());// 10 ✅ 正常

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询