# 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配置(用于覆盖或补充默认行为) - 通用实体基类与结果封装类(影响字段可见性、空值处理、类型识别等) - 枚举定义(影响枚举序列化策略) - 全局异常处理器(影响错误响应体的序列化形态) ```mermaid 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](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) 章节来源 - [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ## 核心组件 - 全局Jackson配置类:集中管理ObjectMapper的序列化/反序列化特性、模块注册、时区与日期格式、枚举策略、空值处理、循环引用策略、大小写转换、属性可见性等。 - 通用实体基类:通过注解控制字段是否参与序列化、忽略特定字段、设置默认值等,从而统一数据模型表现。 - 结果封装类:统一接口返回结构,配合Jackson配置确保空值、枚举、时间等字段的一致序列化。 - 枚举定义:决定枚举序列化为字符串还是数字,以及命名风格。 - 全局异常处理器:将异常转换为统一的Result结构,保证错误响应体符合全局序列化策略。 章节来源 - [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java) - [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) ## 架构总览 下图展示了Spring MVC请求进入后,Jackson如何参与请求体解析与响应体序列化的整体流程,以及与全局异常处理的协作关系。 ```mermaid 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 : "按全局配置进行序列化
日期/枚举/空值/循环引用等" Controller-->>Handler : "抛出异常" Handler->>Jackson : "将异常信息序列化为统一Result" Handler-->>Client : "错误响应(JSON)" ``` 图表来源 - [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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) ## 详细组件分析 ### 全局Jackson配置(JacksonConfig) - 目标:统一ObjectMapper行为,避免在各处重复配置,确保全系统一致的序列化/反序列化策略。 - 关注点: - 特性开关:如忽略未知字段、忽略空值、禁用单引号、禁用大写转小写等。 - 模块注册:如JSR-310日期模块、Guava模块、JDK集合模块等。 - 时区与日期格式:统一时区、ISO或自定义格式。 - 枚举策略:统一以字符串或数字形式序列化。 - 循环引用:启用或禁用循环引用检测及异常策略。 - 大小写与可见性:字段名大小写转换规则、访问器可见性。 - 自定义序列化器/反序列化器:针对特殊类型的编解码扩展。 - 最佳实践: - 使用工厂方法创建ObjectMapper实例,并在WebMvcConfigurer中注册为HttpMessageConverter。 - 对敏感字段使用注解排除,而非全局忽略。 - 对复杂嵌套对象开启循环引用检测,避免StackOverflow。 - 对大对象分页或流式处理,减少内存占用。 章节来源 - [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java) ### 通用实体与结果封装(BaseEntity / OwnedEntity / Result / PageResult) - BaseEntity/OwnedEntity: - 通常包含公共字段(如ID、创建/更新时间、归属信息等),可通过注解控制是否参与序列化。 - 对不需要输出的字段(如密码、内部状态)进行忽略,降低响应体积。 - Result/PageResult: - 统一成功/失败码与消息,结合Jackson配置确保空值不污染响应体。 - 分页数据结构需明确元素类型,避免泛型擦除导致的反序列化问题。 章节来源 - [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 / HasValueEnum) - 推荐策略: - 以字符串形式序列化,提升可读性与兼容性。 - 若需要数值化,应明确映射关系并提供校验。 - 注意事项: - 保持枚举常量命名一致,避免前后端不一致导致解析失败。 - 新增枚举时需考虑向后兼容,必要时提供别名或降级策略。 章节来源 - [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) ### 全局异常处理与JSON输出(GlobalExceptionHandlerAdvice) - 作用:捕获控制器层异常,统一转换为Result结构,确保错误响应体符合全局序列化策略。 - 关键点: - 异常信息脱敏,避免泄露敏感细节。 - 区分业务异常与系统异常,返回不同状态码。 - 结合Jackson配置,确保异常堆栈、参数校验错误等字段正确序列化。 章节来源 - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) ### 应用配置(application.yml) - 用途:覆盖或补充默认Jackson行为,如时区、日期格式、是否忽略空值等。 - 建议: - 将环境差异配置(如开发/生产)放在yml中,便于切换。 - 谨慎开启调试开关,生产环境关闭冗余日志与调试输出。 章节来源 - [application.yml](file://crm-app/src/main/resources/application.yml) ## 依赖关系分析 - JacksonConfig依赖Spring容器提供的ObjectMapper与WebMvcConfigurer,负责注册转换器。 - 实体与枚举作为数据载体,受Jackson配置影响其序列化行为。 - 全局异常处理器依赖Jackson将异常对象序列化为统一响应体。 ```mermaid 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](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java) - [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) 章节来源 - [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) ## 性能考虑 - 对象复用:尽量复用ObjectMapper实例,避免频繁创建带来的开销。 - 惰性加载:对大字段或关联数据按需加载,减少不必要的序列化。 - 空值过滤:合理配置忽略空值,减小响应体体积。 - 循环引用:启用循环引用检测,避免深度嵌套导致的栈溢出。 - 流式处理:对超大列表采用分页或流式输出,降低内存峰值。 - 模块裁剪:仅注册必要模块,减少初始化时间与内存占用。 - 缓存策略:对静态元数据(如字典、枚举映射)进行缓存,避免重复计算。 [本节为通用指导,无需具体文件来源] ## 故障排查指南 - 常见问题 - 日期格式不一致:检查时区与格式配置,确认JSR-310模块是否注册。 - 枚举解析失败:确认枚举序列化策略与前端期望一致。 - 空值污染响应体:检查忽略空值配置与字段注解。 - 循环引用异常:启用循环引用检测或调整数据结构。 - 未知字段报错:根据需求选择忽略未知字段或严格校验。 - 定位步骤 - 查看全局异常处理器返回的错误结构,确认异常信息是否脱敏。 - 对比application.yml与JacksonConfig的配置优先级。 - 使用最小可复现示例隔离问题,逐步缩小范围。 - 修复建议 - 统一枚举与日期格式,增加单元测试覆盖边界情况。 - 对敏感字段使用注解排除,避免全局忽略带来的副作用。 - 对大对象进行分页或分片处理,监控内存与GC指标。 章节来源 - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ## 结论 通过集中式的Jackson配置与统一的实体/结果封装,项目实现了稳定、一致的JSON序列化策略。配合合理的性能优化与安全配置,可在保证可读性与兼容性的同时,提升系统的可扩展性与可维护性。建议在新增数据类型或变更序列化行为时,同步更新文档与测试用例,确保前后端契约的一致性。 [本节为总结性内容,无需具体文件来源] ## 附录 ### 自定义序列化器与反序列化器实现要点 - 何时使用 - 复杂类型(如金额、坐标、加密串)需要特殊编解码。 - 历史兼容:旧字段名与新字段名的映射。 - 安全脱敏:对敏感信息进行掩码或哈希。 - 实现步骤 - 继承JsonSerializer/JsonDeserializer,重写序列化/反序列化逻辑。 - 在JacksonConfig中注册自定义模块,使ObjectMapper生效。 - 编写单元测试覆盖正常与异常路径。 - 注意事项 - 保持幂等性与线程安全。 - 避免在序列化过程中执行耗时操作。 - 对输入进行严格校验,防止恶意数据注入。 [本节为通用指导,无需具体文件来源] ### JSON Schema验证与API版本兼容 - JSON Schema验证 - 在入参入口处引入Schema校验,拦截非法请求。 - 对关键字段设置必填、长度、格式等约束。 - 将校验错误统一转换为Result结构,便于前端处理。 - API版本兼容 - 使用版本号前缀或Accept头区分版本。 - 对废弃字段保留但标记为可选,提供迁移指引。 - 通过适配器模式对旧版数据进行转换,保证向后兼容。 [本节为通用指导,无需具体文件来源] ### 安全配置最佳实践 - 输入校验:对所有外部输入进行白名单校验与长度限制。 - 输出脱敏:对敏感字段进行掩码或移除。 - 循环引用保护:启用检测并限制最大深度。 - 拒绝未知字段:在生产环境开启严格模式,避免注入风险。 - 日志脱敏:避免记录敏感信息与完整堆栈。 [本节为通用指导,无需具体文件来源]