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
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)目录
简介
本文件面向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头区分版本。
- 对废弃字段保留但标记为可选,提供迁移指引。
- 通过适配器模式对旧版数据进行转换,保证向后兼容。
[本节为通用指导,无需具体文件来源]
安全配置最佳实践
- 输入校验:对所有外部输入进行白名单校验与长度限制。
- 输出脱敏:对敏感字段进行掩码或移除。
- 循环引用保护:启用检测并限制最大深度。
- 拒绝未知字段:在生产环境开启严格模式,避免注入风险。
- 日志脱敏:避免记录敏感信息与完整堆栈。
[本节为通用指导,无需具体文件来源]