当前位置: 首页 > news >正文

ResponseUtil.out 方法分析

文章目录

      • 1. 问题背景
      • 2. `ResponseUtil.out` 方法分析
        • a. 方法功能
        • b. 序列化过程
        • c. 注解 `@JsonInclude(JsonInclude.Include.NON_NULL)` 的作用
      • 3. Java 对象如何被序列化为 JSON
      • 4. 序列化的时机
      • 5. 谁操作序列化
      • 6. 自动序列化的条件
      • 7. 总结
      • 8. 可能的问题和注意

1. 问题背景

  • AdminAdminDTO 上添加 @JsonInclude(JsonInclude.Include.NON_NULL) 注解后,Java 对象是否会自动序列化为 JSON 并返回给前端,以及这个序列化过程在什么时候发生、由谁操作的。
  • 现在有了 ResponseUtil.java,我们可以更具体地分析 ResponseUtil.out 方法如何处理 AdminAdminDTO,以及序列化的细节。

2. ResponseUtil.out 方法分析

ResponseUtil.out 方法定义如下:

public static void out(HttpServletResponse response, BaseResult result) {
    ObjectMapper mapper = new ObjectMapper();
    PrintWriter writer = null;
    response.setStatus(HttpStatus.OK.value());
    response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
    try {
        writer = response.getWriter();
        mapper.writeValue(writer, result);
        writer.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (writer != null) {
            writer.flush();
            writer.close();
        }
    }
}
a. 方法功能
  • ResponseUtil.out 是一个工具方法,用于将 BaseResult 对象(包含 AdminAdminDTO)序列化为 JSON 并写入 HttpServletResponse,最终以 JSON 格式返回给前端。
  • 它使用 Jackson 库(com.fasterxml.jackson.databind.ObjectMapper)进行序列化。
b. 序列化过程
  • 输入BaseResult result,其中 resultBaseResult.success(adminAdminDTO) 的调用结果,adminAdminDTO 是一个 AdminAdminDTO 实例。

  • 步骤

    1. 创建 ObjectMapper

      • ObjectMapper mapper = new ObjectMapper(); 实例化一个 Jackson ObjectMapper,这是 Jackson 进行 JSON 序列化和反序列化的核心工具。
      • ObjectMapper 默认会考虑类的注解(如 @JsonInclude)、字段的 getter/setter 方法以及 Jackson 的配置。
    2. 设置响应头

      • response.setStatus(HttpStatus.OK.value()); 设置 HTTP 状态码为 200(成功)。
      • response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); 设置响应内容的 MIME 类型为 application/json;charset=UTF-8,表明返回的是 JSON 格式数据。
    3. 获取 PrintWriter 并序列化

      • writer = response.getWriter(); 获取 HttpServletResponse 的输出流,用于写入 JSON 数据。
      • mapper.writeValue(writer, result); 使用 ObjectMapperBaseResult 对象(包含 AdminAdminDTO)序列化为 JSON 字符串,并写入 PrintWriter
      • Jackson 会遍历 BaseResultAdminAdminDTO 的字段,基于 getter 方法和注解(如 @JsonInclude(JsonInclude.Include.NON_NULL))生成 JSON。
    4. 刷新和关闭流

      • writer.flush(); 确保数据写入输出流。
      • writer.close(); 关闭 PrintWriter,释放资源。
  • 输出:最终生成一个 JSON 字符串(如你提供的日志),通过 HTTP 响应返回给前端。例如:

    {"code":0,"msg":"成功","data":{"communityLinkEditor":false,"copywritingEditor":false,"createdDate":1677778199000,...,"vip":true}}
    
c. 注解 @JsonInclude(JsonInclude.Include.NON_NULL) 的作用
  • AdminAdminDTO 上的 @JsonInclude(JsonInclude.Include.NON_NULL) 会在序列化时生效,由 Jackson 的 ObjectMapper 应用。
  • Jackson 会检查 AdminAdminDTO 的每个字段:
    • 如果字段值为 null,不会序列化到 JSON(例如 logologoMin 等未设置的字段)。
    • 如果字段值非 null(包括 false0、字符串等),会序列化到 JSON(例如 fakeComparor: trueisVip: true)。
  • 这解释了为什么你的日志中未返回 null 值的字段(如 logologoMin),但返回了 true 或其他非 null 值的字段(如 fakeComparor: true)。

3. Java 对象如何被序列化为 JSON

  • 过程

    1. AdminAdminDTO 是一个 Java 对象,包含字段和 getter/setter 方法。
    2. Jackson 的 ObjectMapper 通过反射访问 AdminAdminDTO 的 getter 方法(如 isFakeComparor()isVip() 等),获取字段值。
    3. 根据字段的注解(如 @JsonInclude)、字段值和 ObjectMapper 的配置,Jackson 生成 JSON 字符串。
    4. JSON 字符串被写入 HttpServletResponse,返回给前端。
  • 字段映射

    • 字段如 isVip 被序列化为 "vip": true(见之前的分析,可能是 Jackson 的布尔属性命名规则或未显式注解导致)。
    • 字段如 fakeComparor 被序列化为 "fakeComparor": true,因为它有明确的 getter/setter(isFakeComparor()setFakeComparor(boolean))。

4. 序列化的时机

  • 序列化发生在 MyAuthenticationSuccessHandler.onAuthenticationSuccess 调用 ResponseUtil.out 时:
    • 用户通过 /admin/signIn/admin/signInByPhone 登录,触发 MyAuthenticationSuccessHandler.onAuthenticationSuccess
    • onAuthenticationSuccess 构建 AdminAdminDTO 对象。
    • 调用 ResponseUtil.out(response, BaseResult.success(adminAdminDTO)),触发序列化。
  • 具体时间点是 HTTP 响应生成时,ObjectMapper.writeValueBaseResultAdminAdminDTO 转换为 JSON 字符串。

5. 谁操作序列化

  • 直接操作者ResponseUtil.out 方法中的 ObjectMapper.writeValue(writer, result) 由 Jackson 的 ObjectMapper 执行序列化。
  • 触发者
    • 后端开发者编写的代码(MyAuthenticationSuccessHandlerResponseUtil)调用了 ObjectMapper,触发序列化。
    • Spring MVC 框架负责处理 HttpServletResponse 和 JSON 转换。如果 ResponseUtil.out 没有显式指定 JSON 库,Spring MVC 可能会通过 MappingJackson2HttpMessageConverter(默认 Jackson 集成)自动完成序列化。
  • JSON 库:在你的代码中,ResponseUtil 显式使用了 Jackson(com.fasterxml.jackson.databind.ObjectMapper),因此序列化由 Jackson 执行。但如果项目配置了 FastJSON(通过 FastJsonHttpMessageConverter),可能需要确认是否覆盖了 Jackson 的行为。

6. 自动序列化的条件

  • 添加 @JsonInclude(JsonInclude.Include.NON_NULL) 后,序列化是“自动”的,前提是:
    1. AdminAdminDTO 被传递给支持 JSON 序列化的方法(如 ResponseUtil.out 或 Spring MVC 的控制器返回)。
    2. 项目配置了 Jackson 作为 JSON 序列化库,并启用了相关注解支持(@JsonInclude 有效)。
    3. 字段有 getter 方法(AdminAdminDTO 中的所有字段都有 getter 和 setter,因此满足条件)。

7. 总结

  • 是否自动序列化:是的,AdminAdminDTO 会自动序列化为 JSON 并返回给前端,前提是它被传递给 ResponseUtil.out 或类似方法,Jackson 负责序列化。
  • 序列化的时机:序列化发生在 MyAuthenticationSuccessHandler.onAuthenticationSuccess 中的 ResponseUtil.out 调用时,具体由 Jackson 的 ObjectMapper.writeValue 执行。
  • 谁操作序列化
    • 由后端开发者编写的 ResponseUtil.out 触发序列化。
    • 序列化操作由 Jackson 的 ObjectMapper 执行,框架(Spring MVC)通过 MappingJackson2HttpMessageConverterResponseUtil 协调。
  • Java 对象如何成为 JSONAdminAdminDTO 对象通过其 getter 方法和注解(如 @JsonInclude)被 Jackson 序列化为 JSON 字符串,写入 HttpServletResponse,最终以 application/json 格式返回给前端。

8. 可能的问题和注意

  • 如果项目同时配置了 FastJSON(通过 FastJsonHttpMessageConverter),需要确认 ResponseUtil.out 是否优先使用 Jackson,还是被 FastJSON 覆盖。
  • 如果 AdminAdminDTO 中的某些字段未返回(如 logologoMin),可能是因 @JsonInclude(JsonInclude.Include.NON_NULL) 过滤了 null 值。
  • 如果需要调试,建议在 ResponseUtil.out 中打印序列化前的 adminAdminDTO 和序列化后的 JSON:
    logger.info("AdminAdminDTO before serialization: {}", adminAdminDTO);
    logger.info("AdminAdminDTO JSON: {}", mapper.writeValueAsString(result));
    

在这里插入图片描述

相关文章:

  • Golang连接使用SqlCipher
  • android studio 界面启动模拟器无反应——从命令行启动模拟器
  • 一分钟学会JavaScript 变量
  • vxe-table实现动态列
  • 2025年度福建省职业院校技能大赛高职组“信息安全管理与评估”赛项规程
  • [c++]--类和对象
  • 【uniapp*vue3】app/h5 webview通讯方案
  • UE5中按钮圆角,设置边框
  • Redis使用手册
  • 使用Hardhat实现ERC20 代币合约详解
  • 通俗易懂的DOM事件模型指南
  • 数据结构:哈希表(unordered_map)
  • 1.13作业
  • 人工智能之自动驾驶技术体系
  • 大学本科教务系统设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点
  • 长尾关键词优化三步法:提升SEO搜索排名实战
  • MATLAB | 设置滑动窗口计算栅格数据的CV变异系数
  • MySQL数据库表约束详解
  • 一些时间方法
  • python入门 介绍及变量的使用
  • 证监会强化上市公司募资监管七要点:超募资金不得补流、还贷
  • 中国巴西关于乌克兰危机的联合声明
  • 外交部:中方期待印巴巩固和延续停火势头,避免冲突再起
  • 《三餐四季》广东篇今晚开播:食在岭南,遇见百味
  • 非洲雕刻艺术有着怎样的“变形之美”
  • 欧盟决意与俄罗斯能源彻底决裂之际,美国谋划新生意:进口俄气对欧转售