springboot 序列化/反序列化
对于我们新手来说,似乎按照对应的规则配置, 就能接受返回参数, controller层上得到或返回一个对象; 其实内部有个序列化/反序列化操作,上文实体类的注解就需要我们理解一下这些逻辑了为什么必须序列化/反序列化HTTP 协议传输的数据本质上是文本字符串它不认识 Java 对象或 JavaScript 对象。所以对象在传输前必须转换成字符串接收方再把字符串还原成对象。后端Java对象 ──[序列化]──→JSON字符串 ──[HTTP传输]──→JSON字符串 ──[反序列化]──→ 前端JS对象 前端JS对象 ──[序列化]──→JSON字符串 ──[HTTP传输]──→JSON字符串 ──[反序列化]──→ 后端Java对象后端 → 前端// 后端Java 对象OrderordernewOrder();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(resres.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 参数?id1namexxx✅ 但方式不同用 URL 编码不是 JSON 序列化这也是为什么前面讨论的 JsonFormat、JSONField、DateTimeFormat 这些注解如此重要——它们就是在控制序列化和反序列化过程中日期字段的格式。规则JSON 序列化框架FastJSON、Jackson的默认规则是序列化把对象中所有非静态、非瞬态的字段或有 getter 的属性转成 JSON 键值对反序列化把 JSON 中的键值对按字段名匹配自动赋值给对象的对应属性通过 setter 或直接字段访问DatapublicclassOrder{privateLongid;privateStringname;privateIntegerrelatedFundProjectCount;// 普通属性什么都没加}// 序列化Java → JSONOrderordernewOrder();order.setId(1L);order.setName(测试订单);order.setRelatedFundProjectCount(5);StringjsonJSON.toJSONString(order);// 输出{id:1,name:测试订单,relatedFundProjectCount:5} ✅ 正常// 反序列化JSON → JavaStringjsonInput{\id\:2,\name:另一个订单,relatedFundProjectCount:10};Orderorder2JSON.parseObject(jsonInput,Order.class);System.out.println(order2.getRelatedFundProjectCount());// 10 ✅ 正常类的转换实体类里, 以下常见类型都不需要加任何注解框架内置了转换器类型示例基本类型及包装类Integer、Long、Boolean、Double字符串String集合List、Set、Map数组String[]、Integer[]嵌套对象User、OrderItem等自定义类只有框架不知道该怎么转的类型才需要加注解或自定义转换器类型问题解决方案Date/LocalDateTime格式不统一JSONField(format ...)LocalDate格式不统一JSONField(format ...)枚举默认输出序号或名称可能不符合需求JSONField或自定义序列化器特殊对象如BigDecimal需要指定精度默认行为不满足自定义序列化器普通属性Integer、String、Long 等什么都不加序列化和反序列化都能正常工作。加注解如 JSONField只是用来覆盖默认行为比如改格式、改字段名、忽略字段等。不需要特殊处理时就不用加。JacksonSpring Boot 默认为什么要写Data除了在代码里 使用set, get方法, 用这个注解的还有个重要作用就是 Spring Boot 默认Jackson默认的字段可见性策略是序列化找 public 的 getter 方法 或 public 的字段反序列化找 public 的 setter 方法 或 public 的字段所以不写 getter/setter 也能序列化/反序列化只是 Jackson 默认配置下不行需要额外配置。而 FastJSON 和 Lombok 方案天然支持。JSON.toJSONString, JSON.parseObject有时候 数据库存了一个json类型的字符串, 用的就是上的方法// 序列化Java → JSONOrderordernewOrder();order.setId(1L);order.setName(测试订单);order.setRelatedFundProjectCount(5);StringjsonJSON.toJSONString(order);// 输出{id:1,name:测试订单,relatedFundProjectCount:5} ✅ 正常// 反序列化JSON → JavaStringjsonInput{\id\:2,\name:另一个订单,relatedFundProjectCount:10};Orderorder2JSON.parseObject(jsonInput,Order.class);System.out.println(order2.getRelatedFundProjectCount());// 10 ✅ 正常