ResponseUtil.out 方法分析

news2025/4/19 13:00:35

文章目录

      • 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));
    

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2303446.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Flask框架的食谱数据可视化分析系统的设计与实现

【Flask】基于Flask框架的食谱数据可视化分析系统的设计与实现 (完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 在当今数字化时代,信息可视化已成为一种高效的数据理解和传播手段。…

java后端开发day18--学生管理系统

(以下内容全部来自上述课程) 1.业务分析并搭建主菜单 1.需求 采取控制台的方式去书写学生管理系统 2.分析 1.初始菜单 2.学生类 属性:id,姓名,年龄,家庭住址 3.添加功能 键盘录入每一个学生信息并添…

工厂车辆排队系统

工厂车辆排队系统是一种智能化调度管理系统,用于管理工厂内部所有车辆的进出和排队方式。采用JAVA语言开发,对接了仰邦控制卡硬件。 工厂车辆排队系统是一种智能化调度管理系统,用于管理工厂内部所有车辆的进出和排队方式。该系统可以提高车…

深度理解多态的底层实现

前言 首先先回顾一下上次的知识 一、多态的概念 多态(polymorphism)的概念:通俗来说,就是多种形态。多态分为编译时多态(静态多态)和运⾏时多态(动态多态),这⾥我们重点讲运⾏时多态,编译时多态(静态多态)和运⾏时多态(动态多态…

空字符串““、空白字符串“ “和 null 三者的区别

空字符串、空白字符串和 null 三者的区别表格: 类型定义示例长度是否有值空字符串字符串长度为 0,但不是 null,即存在一个有效的空字符串对象。""0有值(空值)空白字符串字符串包含空格、制表符等空白字符&a…

在mfc中使用自定义三维向量类和计算多个三维向量的平均值

先添加一个普通类, Vector3.h, // Vector3.h: interface for the Vector3 class. // //#if !defined(AFX_VECTOR3_H__53D34D26_95FF_4377_BD54_57F4271918A4__INCLUDED_) #define AFX_VECTOR3_H__53D34D26_95FF_4377_BD54_57F4271918A4__INCLUDED_#if _MSC_VER > 1000 #p…

多线程和并发篇

多线程和并发篇 创建一个对象时底层汇编指令实现步骤(cpu可能会进行指令重排序):一、二、三级缓存的实现:并发编程三要素:线程的五大状态:创建线程的三种方式:线程的特征和状态:Thre…

【3.5JavaScript】JavaScript字符串对象

文章目录 1.获取字符串长度2.大小写转换3.获取某一个字符4.截取字符串5.替换字符串6.分割字符串7.检索字符串位置8.例题:统计某一个字符的个数 在 JavaScript 中,对象是非常重要的知识点。对象分为两种:一种是 ”自定义对象“,另…

路由基本配置

学习目标 • 根据拓扑图进行网络布线。 • 清除启动配置并将路由器重新加载为默认状态。 • 在路由器上执行基本配置任务。 • 配置并激活以太网接口。 • 测试并检验配置。 • 思考网络实施方案并整理成文档。 任务 1:网络布线 使用适当的电缆类型连接网络设备。…

windows上vscode cmake工程搭建

安装vscode插件: 1.按装fastc(主要是安装MinGW\mingw64比较方便) 2.安装C,cmake,cmake tools插件 3.准备工作完成之后,按F1,选择cmake:Quick Start就可以创建一个cmake工程。 4.设置Cmake: G…

VUE3+TS+element-plus项目从0开始入门 - 创建项目、认识基本结构

文章目录 写在前面1、创建vue3项目npm create vuelatestnpm i 2、项目结构.vscodevue3结构a、项目树结构b、package.jsonc、tsconfig.jsond、index.htmld、srce、main.tsf、App.vue 写在前面 开前请自行下载vs code、node.js, 在vs code里面安装Vue - Official插件。本文使用的…

shared_ptr 不析构的问题记录

片段1: 片段2: 你们猜 哪个有问题 ?

原生稀疏注意力机制(NSA):硬件对齐且可原生训练的稀疏注意力机制-论文阅读

摘要 长上下文建模对于下一代语言模型至关重要,但标准注意力机制的高计算成本带来了巨大的计算挑战。稀疏注意力提供了一种在保持模型能力的同时提高效率的有前途的方向。本文提出了一种名为 NSA(原生可训练稀疏注意力机制) 的方法&#xff…

从0到1:固件分析

固件分析 0x01 固件提取 1、从厂商官网下载 例如D-link的固件: https://support.dlink.com/resource/products/ 2、代理或镜像设备更新时的流量 发起中间人攻击MITM #启用IP转发功能 echo 1 > /proc/sys/net/ipv4/ip_forward#配置iptables,将目…

conda、anaconda、pip、pytorch、tensorflow有什么区别?

先画一张图,可以大致看出它们的区别和关联: pytorch、tensorflow都是Python的第三方库,相当于封装的代码工具集库,通过import导入使用。这两个都是深度学习框架,用来搭建AI模型什么的,使用范围非常之广&…

项目设置内网 IP 访问实现方案

在我们平常的开发工作中,项目开发、测试完成后进行部署上线。比如电商网站、新闻网站、社交网站等,通常对访问不会进行限制。但是像企业内部网站、内部管理系统等,这种系统一般都需要限制访问,比如内网才能访问等。那么一个网站应…

Vue面试2

1.跨域问题以及如何解决跨域 跨域问题(Cross-Origin Resource Sharing, CORS)是指在浏览器中,当一个资源试图从一个不同的源请求另一个资源时所遇到的限制。这种限制是浏览器为了保护用户安全而实施的一种同源策略(Same-origin p…

合合信息2025届春季校园招聘全面启动!

世界因你而AI,合合信息2025届春季校园招聘启动! 我们是谁? 我们是一家行业领先的人工智能及大数据科技企业 18年深耕AI领域,C端产品与B端服务布局矩阵完善 9.4亿全球累计用户首次下载量💥 来到这里你能得到什么&a…

shiro代码层面追踪

文章目录 环境漏洞分析硬编码 反序列化Gadget构造 环境 环境搭建:https://blog.csdn.net/qq_44769520/article/details/123476443 漏洞分析 硬编码 shiro是对rememberMe这个cookie进⾏反序列化的时候出现了问题。 相应代码 // // Source code recreated from …

虚拟机网络ssh连接失败,没有网络

vscode进行ssh时连接失败,发现是虚拟机没有网络。 虚拟机ping不通www.baidu.com但可以ping通内网 ping 8.8.8.8ping不通。 sudo dhclient -r ens33 sudo dhclient ens33 ip route show可以了。 20250221记录:不知道是不是重启了虚拟机还是咋了&#…