You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

16 KiB

Jackson序列化配置

**本文引用的文件** - [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [StatusEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/StatusEnum.java) - [HasValueEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/HasValueEnum.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向CRM后端中的Jackson序列化与反序列化配置,系统性说明全局JSON序列化策略、日期格式化、枚举处理、空值过滤等关键配置项;并给出自定义序列化器/反序列化器的实现方法、大对象处理、循环引用检测与性能优化技巧。同时提供JSON Schema验证、API版本兼容性与安全配置的最佳实践建议,帮助团队在统一规范下高效、稳定地输出一致的JSON数据。

项目结构

本项目采用多模块组织,Jackson相关的全局配置集中在基础模块中,便于各业务模块复用。与序列化相关的核心文件包括:

  • 全局Jackson配置类
  • 应用级YAML配置(用于覆盖或补充默认行为)
  • 通用实体基类与结果封装类(影响字段可见性、空值处理、类型识别等)
  • 枚举定义(影响枚举序列化策略)
  • 全局异常处理器(影响错误响应体的序列化形态)
graph TB
subgraph "基础模块 crm-base"
JConf["JacksonConfig.java"]
BaseEnt["BaseEntity.java"]
OwnedEnt["OwnedEntity.java"]
ResultCls["Result.java"]
PageRes["PageResult.java"]
StatusEnum["StatusEnum.java"]
HasValEnum["HasValueEnum.java"]
GEx["GlobalExceptionHandlerAdvice.java"]
end
subgraph "应用模块 crm-app"
AppCfg["application.yml"]
end
AppCfg --> JConf
JConf --> BaseEnt
JConf --> OwnedEnt
JConf --> ResultCls
JConf --> PageRes
JConf --> StatusEnum
JConf --> HasValEnum
GEx --> ResultCls

图表来源

  • JacksonConfig.java
  • application.yml
  • BaseEntity.java
  • OwnedEntity.java
  • Result.java
  • PageResult.java
  • StatusEnum.java
  • HasValueEnum.java
  • GlobalExceptionHandlerAdvice.java

章节来源

  • JacksonConfig.java
  • application.yml

核心组件

  • 全局Jackson配置类:集中管理ObjectMapper的序列化/反序列化特性、模块注册、时区与日期格式、枚举策略、空值处理、循环引用策略、大小写转换、属性可见性等。
  • 通用实体基类:通过注解控制字段是否参与序列化、忽略特定字段、设置默认值等,从而统一数据模型表现。
  • 结果封装类:统一接口返回结构,配合Jackson配置确保空值、枚举、时间等字段的一致序列化。
  • 枚举定义:决定枚举序列化为字符串还是数字,以及命名风格。
  • 全局异常处理器:将异常转换为统一的Result结构,保证错误响应体符合全局序列化策略。

章节来源

  • JacksonConfig.java
  • BaseEntity.java
  • OwnedEntity.java
  • Result.java
  • PageResult.java
  • StatusEnum.java
  • HasValueEnum.java
  • GlobalExceptionHandlerAdvice.java

架构总览

下图展示了Spring MVC请求进入后,Jackson如何参与请求体解析与响应体序列化的整体流程,以及与全局异常处理的协作关系。

sequenceDiagram
participant Client as "客户端"
participant Controller as "控制器"
participant Handler as "全局异常处理器"
participant Jackson as "Jackson ObjectMapper"
participant Model as "实体/DTO/枚举"
Client->>Controller : "HTTP 请求(含JSON)"
Controller->>Jackson : "反序列化请求体为Java对象"
Jackson-->>Controller : "已解析的对象"
Controller->>Model : "执行业务逻辑"
Controller-->>Client : "返回Result/PageResult等响应体"
Note over Jackson,Model : "按全局配置进行序列化<br/>日期/枚举/空值/循环引用等"
Controller-->>Handler : "抛出异常"
Handler->>Jackson : "将异常信息序列化为统一Result"
Handler-->>Client : "错误响应(JSON)"

图表来源

  • JacksonConfig.java
  • GlobalExceptionHandlerAdvice.java
  • Result.java
  • PageResult.java

详细组件分析

全局Jackson配置(JacksonConfig)

  • 目标:统一ObjectMapper行为,避免在各处重复配置,确保全系统一致的序列化/反序列化策略。
  • 关注点:
    • 特性开关:如忽略未知字段、忽略空值、禁用单引号、禁用大写转小写等。
    • 模块注册:如JSR-310日期模块、Guava模块、JDK集合模块等。
    • 时区与日期格式:统一时区、ISO或自定义格式。
    • 枚举策略:统一以字符串或数字形式序列化。
    • 循环引用:启用或禁用循环引用检测及异常策略。
    • 大小写与可见性:字段名大小写转换规则、访问器可见性。
    • 自定义序列化器/反序列化器:针对特殊类型的编解码扩展。
  • 最佳实践:
    • 使用工厂方法创建ObjectMapper实例,并在WebMvcConfigurer中注册为HttpMessageConverter。
    • 对敏感字段使用注解排除,而非全局忽略。
    • 对复杂嵌套对象开启循环引用检测,避免StackOverflow。
    • 对大对象分页或流式处理,减少内存占用。

章节来源

  • JacksonConfig.java

通用实体与结果封装(BaseEntity / OwnedEntity / Result / PageResult)

  • BaseEntity/OwnedEntity:
    • 通常包含公共字段(如ID、创建/更新时间、归属信息等),可通过注解控制是否参与序列化。
    • 对不需要输出的字段(如密码、内部状态)进行忽略,降低响应体积。
  • Result/PageResult:
    • 统一成功/失败码与消息,结合Jackson配置确保空值不污染响应体。
    • 分页数据结构需明确元素类型,避免泛型擦除导致的反序列化问题。

章节来源

  • BaseEntity.java
  • OwnedEntity.java
  • Result.java
  • PageResult.java

枚举处理(StatusEnum / HasValueEnum)

  • 推荐策略:
    • 以字符串形式序列化,提升可读性与兼容性。
    • 若需要数值化,应明确映射关系并提供校验。
  • 注意事项:
    • 保持枚举常量命名一致,避免前后端不一致导致解析失败。
    • 新增枚举时需考虑向后兼容,必要时提供别名或降级策略。

章节来源

  • StatusEnum.java
  • HasValueEnum.java

全局异常处理与JSON输出(GlobalExceptionHandlerAdvice)

  • 作用:捕获控制器层异常,统一转换为Result结构,确保错误响应体符合全局序列化策略。
  • 关键点:
    • 异常信息脱敏,避免泄露敏感细节。
    • 区分业务异常与系统异常,返回不同状态码。
    • 结合Jackson配置,确保异常堆栈、参数校验错误等字段正确序列化。

章节来源

  • GlobalExceptionHandlerAdvice.java

应用配置(application.yml)

  • 用途:覆盖或补充默认Jackson行为,如时区、日期格式、是否忽略空值等。
  • 建议:
    • 将环境差异配置(如开发/生产)放在yml中,便于切换。
    • 谨慎开启调试开关,生产环境关闭冗余日志与调试输出。

章节来源

  • application.yml

依赖关系分析

  • JacksonConfig依赖Spring容器提供的ObjectMapper与WebMvcConfigurer,负责注册转换器。
  • 实体与枚举作为数据载体,受Jackson配置影响其序列化行为。
  • 全局异常处理器依赖Jackson将异常对象序列化为统一响应体。
classDiagram
class JacksonConfig {
+configureObjectMapper()
+registerModules()
+setSerializationFeatures()
+setDeserializationFeatures()
+registerCustomSerializers()
}
class BaseEntity {
+id
+createTime
+updateTime
}
class OwnedEntity {
+ownerId
+tenantId
}
class Result {
+code
+message
+data
}
class PageResult {
+list
+total
+page
+size
}
class StatusEnum
class HasValueEnum
class GlobalExceptionHandlerAdvice {
+handleException()
}
JacksonConfig --> BaseEntity : "影响序列化"
JacksonConfig --> OwnedEntity : "影响序列化"
JacksonConfig --> Result : "影响序列化"
JacksonConfig --> PageResult : "影响序列化"
JacksonConfig --> StatusEnum : "枚举策略"
JacksonConfig --> HasValueEnum : "枚举策略"
GlobalExceptionHandlerAdvice --> Result : "生成响应体"

图表来源

  • JacksonConfig.java
  • BaseEntity.java
  • OwnedEntity.java
  • Result.java
  • PageResult.java
  • StatusEnum.java
  • HasValueEnum.java
  • GlobalExceptionHandlerAdvice.java

章节来源

  • JacksonConfig.java
  • GlobalExceptionHandlerAdvice.java

性能考虑

  • 对象复用:尽量复用ObjectMapper实例,避免频繁创建带来的开销。
  • 惰性加载:对大字段或关联数据按需加载,减少不必要的序列化。
  • 空值过滤:合理配置忽略空值,减小响应体体积。
  • 循环引用:启用循环引用检测,避免深度嵌套导致的栈溢出。
  • 流式处理:对超大列表采用分页或流式输出,降低内存峰值。
  • 模块裁剪:仅注册必要模块,减少初始化时间与内存占用。
  • 缓存策略:对静态元数据(如字典、枚举映射)进行缓存,避免重复计算。

[本节为通用指导,无需具体文件来源]

故障排查指南

  • 常见问题
    • 日期格式不一致:检查时区与格式配置,确认JSR-310模块是否注册。
    • 枚举解析失败:确认枚举序列化策略与前端期望一致。
    • 空值污染响应体:检查忽略空值配置与字段注解。
    • 循环引用异常:启用循环引用检测或调整数据结构。
    • 未知字段报错:根据需求选择忽略未知字段或严格校验。
  • 定位步骤
    • 查看全局异常处理器返回的错误结构,确认异常信息是否脱敏。
    • 对比application.yml与JacksonConfig的配置优先级。
    • 使用最小可复现示例隔离问题,逐步缩小范围。
  • 修复建议
    • 统一枚举与日期格式,增加单元测试覆盖边界情况。
    • 对敏感字段使用注解排除,避免全局忽略带来的副作用。
    • 对大对象进行分页或分片处理,监控内存与GC指标。

章节来源

  • GlobalExceptionHandlerAdvice.java
  • application.yml

结论

通过集中式的Jackson配置与统一的实体/结果封装,项目实现了稳定、一致的JSON序列化策略。配合合理的性能优化与安全配置,可在保证可读性与兼容性的同时,提升系统的可扩展性与可维护性。建议在新增数据类型或变更序列化行为时,同步更新文档与测试用例,确保前后端契约的一致性。

[本节为总结性内容,无需具体文件来源]

附录

自定义序列化器与反序列化器实现要点

  • 何时使用
    • 复杂类型(如金额、坐标、加密串)需要特殊编解码。
    • 历史兼容:旧字段名与新字段名的映射。
    • 安全脱敏:对敏感信息进行掩码或哈希。
  • 实现步骤
    • 继承JsonSerializer/JsonDeserializer,重写序列化/反序列化逻辑。
    • 在JacksonConfig中注册自定义模块,使ObjectMapper生效。
    • 编写单元测试覆盖正常与异常路径。
  • 注意事项
    • 保持幂等性与线程安全。
    • 避免在序列化过程中执行耗时操作。
    • 对输入进行严格校验,防止恶意数据注入。

[本节为通用指导,无需具体文件来源]

JSON Schema验证与API版本兼容

  • JSON Schema验证
    • 在入参入口处引入Schema校验,拦截非法请求。
    • 对关键字段设置必填、长度、格式等约束。
    • 将校验错误统一转换为Result结构,便于前端处理。
  • API版本兼容
    • 使用版本号前缀或Accept头区分版本。
    • 对废弃字段保留但标记为可选,提供迁移指引。
    • 通过适配器模式对旧版数据进行转换,保证向后兼容。

[本节为通用指导,无需具体文件来源]

安全配置最佳实践

  • 输入校验:对所有外部输入进行白名单校验与长度限制。
  • 输出脱敏:对敏感字段进行掩码或移除。
  • 循环引用保护:启用检测并限制最大深度。
  • 拒绝未知字段:在生产环境开启严格模式,避免注入风险。
  • 日志脱敏:避免记录敏感信息与完整堆栈。

[本节为通用指导,无需具体文件来源]