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

@JsonView + 单一 DTO:如何实现多场景 JSON 字段动态渲染

@JsonView + 单一 DTO:如何实现多场景 JSON 字段动态渲染

  • @JsonView + 单一 DTO:如何实现多场景 JSON 字段动态渲染
    • 1、@JsonView 注解产生的背景
    • 2、为了满足不同场景下返回对应的属性的做法有哪些?
      • 2.1 最快速的实现则是针对不同场景新建不同的 DTO 对象
      • 2.2 使用 @JsonView 注解实现不同DTO对象的返回
        • 2.2.1 定义同一个 DTO 对象
        • 2.2.2 区分不同的响应视图
        • 2.2.3 Controller 层的调用
        • 2.2.4 简要信息 视图 DTO
        • 2.2.5 详情信息 视图 DTO
      • 2.3 问题已解决(引入原理实现篇)
    • 3、Debug调试篇
      • 3.1 SpringMvc 切入点 对应的核心代码片段
      • 3.2 字段属性序列化核心逻辑
      • 3.3 多种 DTO 视图 Demo 验证
        • 3.3.1 ObjectMapper 配置视图 View
        • 3.3.2 ObjectWriter 配置视图 View
      • 3.4 小结
    • 4、扩展点
      • 4.1 ResponseBodyAdvice接口
      • 4.2 RequestBodyAdvice接口

@JsonView + 单一 DTO:如何实现多场景 JSON 字段动态渲染

1、@JsonView 注解产生的背景

@JsonView 是 Jackson 库提供的一个注解,用于控制 Java 对象序列化为 JSON 时的字段可见性。通过定义不同的“视图”(View),可以灵活地决定哪些字段在特定场景下被序列化,从而避免为不同接口编写多个相似的 DTO 类。

2、为了满足不同场景下返回对应的属性的做法有哪些?

2.1 最快速的实现则是针对不同场景新建不同的 DTO 对象

在这里插入图片描述

细心的童鞋可以发现:虽然是不同的 DTO,但是存在共同的属性,而且比如后面再来一个需求,这个接口仅返回基本信息的字段(外加一个手机号字段),那么我们是不是还需要创建一个新的 DTO 对象呢?如果针对每一个接口返回都定义一个 DTO 对象的话,对于后端代码的维护也是相当的冗余操作,鉴于这种需求,有没有一种对应后端的 其他 解决方案呢?答案是有的。即就是(@JsonView注解)。

2.2 使用 @JsonView 注解实现不同DTO对象的返回

2.2.1 定义同一个 DTO 对象
/*** @Description 用户DTO* @Author Mr.Gao* @Date 2025/4/16 23:43*/
@Getter
@Setter
public class User {/*** 用户姓名*/@JsonView(SimpleInfoView.class)private String username;/*** 用户年龄*/@JsonView(SimpleInfoView.class)private Integer age;/*** 用户性别*/@JsonView(SimpleInfoView.class)private String sex;/*** =================以下信息为用户敏感信息不能给用户返回================*//*** 手机号码*/@JsonView(SensitiveInfoView.class)private String mobileNo;/*** 登录密码*/@JsonView(SensitiveInfoView.class)private String loginPwd;/*** 支付密码*/@JsonView(SensitiveInfoView.class)private String payPwd;
}
2.2.2 区分不同的响应视图
/*** @Description 简单视图展示View信息* @Author Mr.Gao*/
public interface SimpleInfoView {
}------ 视图与视图之间是可以继承的,那么也就实现既包含基础信息字段又包含需要的字段,进而实现不同DTO的返回 ---
/*** @Description 敏感信息* @Author Mr.Gao*/
public interface SensitiveInfoView extends SimpleInfoView {
}
2.2.3 Controller 层的调用
/*** @Description 用户控制层* @Author Mr.Gao* @Date 2025/4/16 23:50*/
@RestController
public class UserController {/*** 模拟从数据库获取用户信息** @return*/public static User getUserInfoFromDB() {User user = new User();user.setUsername("Mr.Gao");user.setAge(18);user.setSex("男");user.setMobileNo("12345678901");user.setLoginPwd("123456");user.setPayPwd("123456");return user;}/*** 获取用户简要信息** @return*/@JsonView(SimpleInfoView.class) // 返回简要信息的视图DTO@GetMapping("/user/getUserSimpleInfo")public User getUserSimpleInfo() {return getUserInfoFromDB();}/*** 获取用户详细信息** @return*/@JsonView(SensitiveInfoView.class)// 返回详情信息的视图DTO@GetMapping("/user/getUserDetailInfo")public User getUserDetailInfo() {return getUserInfoFromDB();}}
2.2.4 简要信息 视图 DTO

在这里插入图片描述

2.2.5 详情信息 视图 DTO

在这里插入图片描述

2.3 问题已解决(引入原理实现篇)

经过上述代码案例操作,确实是可以解决我们后端程序猿的新建多个 DTO 对象的冗余问题,童鞋们可以都试试,但是出于好奇,为了什么在 一个实体对象 DTO 和 controller 层的方法 增加 @JsonView 注解之后就能实现不同视图的效果呢?其中究竟是使用了什么魔法呢?接下来我们继续进入 Debug 调试篇,继续 gank 它。

3、Debug调试篇

3.1 SpringMvc 切入点 对应的核心代码片段

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 字段属性序列化核心逻辑

在这里插入图片描述
在这里插入图片描述

经过上述分析可得,设置视图的核心代码为 objectMapper.writerWithView(serializationView) ,然后调用 objectMapper.writeValueAsString 方法是否可以实现不同视图的 DTO 输出呢?

3.3 多种 DTO 视图 Demo 验证

3.3.1 ObjectMapper 配置视图 View
@Test
public void testJsonViewAnnotationConvertMutiDTOByObjectMapper() throws JsonProcessingException {User user = UserController.getUserInfoFromDB();// @1: 设置序列化视图为SimpleInfoView(输出简要信息)objectMapper.setConfig(objectMapper.getSerializationConfig().withView(SimpleInfoView.class));// @2: 设置序列化视图为SensitiveInfoView(输出详细信息)//objectMapper.setConfig(objectMapper.getSerializationConfig()//        .withView(SensitiveInfoView.class));System.out.println("采用Object序列化视图:" + objectMapper.getSerializationConfig().getActiveView());String JsonResult = objectMapper.writeValueAsString(user);System.out.println(JsonResult);
}
3.3.2 ObjectWriter 配置视图 View
@Test
public void testJsonViewAnnotationConvertMutiDTOByObjectWriter() throws JsonProcessingException {User user = UserController.getUserInfoFromDB();// @1: 设置序列化视图为SimpleInfoView(输出简要信息)//ObjectWriter objectWriter = objectMapper.writerWithView(SimpleInfoView.class);// @2: 设置序列化视图为SensitiveInfoView(输出详细信息)ObjectWriter objectWriter = objectMapper.writerWithView(SensitiveInfoView.class);System.out.println("ObjectWriter中的序列化视图为: " + objectWriter.getConfig().getActiveView());String JsonResult = objectWriter.writeValueAsString(user);System.out.println(JsonResult);
}

3.4 小结

最后,我本地的项目 SpringBoot 版本是 2.6.13,而我的 Pom 文件依赖中仅仅引入了spring-boot-starter-web,我可以确定的是没有引入任何 jackson 包的依赖的,而@JsonView 注解是 jackson 包下的注解,那么只有一种可能,那就是对应的 springboot 的 web 依赖集成了对应 jackson 相关 jar 包,出于好奇的我还是点开了 spring-boot-starter-web 依赖,结果发现确实是这样。
在这里插入图片描述

4、扩展点

4.1 ResponseBodyAdvice接口

对响应的内容可以进行二次包装处理,例如对响应参数内容统一进行签名、加密等逻辑处理。

4.2 RequestBodyAdvice接口

用来对请求的内容进行请求参数重写处理,例如对接收到请求参数统一进行验签、解密等逻辑处理。

综上所述,相信我们已经掌握了 如何通过一个 DTO 对象来渲染不同需求场景下的 DTO 对象,不过存在唯一的缺点,经过 Debug 调试篇我们可以发现,只有在 序列化的时候才会过滤对应的字段,那么如果一个 DTO 对象的属性太多,根据类的单一设计原则还是建议使用新建新的 DTO 对象来完成。所以我觉得可以视情况而定,想要代码的逻辑清晰一些就新建 DTO 实体,想要减少的代码的编码量(即减少 DTO 实体对象)那么就用@JsonView注解实现。
在这里插入图片描述

相关文章:

@JsonView + 单一 DTO:如何实现多场景 JSON 字段动态渲染

JsonView 单一 DTO:如何实现多场景 JSON 字段动态渲染 JsonView 单一 DTO:如何实现多场景 JSON 字段动态渲染1、JsonView 注解产生的背景2、为了满足不同场景下返回对应的属性的做法有哪些?2.1 最快速的实现则是针对不同场景新建不同的 DTO…...

JVM之经典垃圾回收器

一、垃圾回收算法 1. 标记-清除(Mark-Sweep) 步骤: 标记:遍历对象图,标记所有存活对象。清除:回收未被标记的垃圾对象。 特点:简单,但会产生内存碎片。 2. 标记-复制(…...

15 nginx 中默认的 proxy_buffering 导致基于 http 的流式响应存在 buffer, 以 4kb 一批次返回

前言 这也是最近碰到的一个问题 直连 流式 http 服务, 发现 流式响应正常, 0.1 秒接收到一个响应 但是 经过 nginx 代理一层之后, 就发现了 类似于缓冲的效果, 1秒接收到 10个响应 最终 调试 发现是 nginx 的 proxy_buffering 配置引起的 然后 更新 proxy_buffering 为…...

人工智能学习框架完全指南(2025年更新版)

一、核心框架分类与适用场景 人工智能框架根据功能可分为深度学习框架、机器学习框架、强化学习框架和传统工具库,以下是主流工具及选型建议: 1. 深度学习框架 (1)PyTorch 核心优势:动态计算图、灵活性强,适合科研与快速原型开发,支持多模态任务(如NLP、CV) 。技术生…...

安卓手机万能遥控器APP推荐

软件介绍 安卓手机也能当“家电总控台”?这款小米旗下的万能遥控器APP,直接把遥控器做成“傻瓜式操作”——不用配对,不连蓝牙,点开就能操控电视、空调、机顶盒,甚至其他品牌的电器!雷总这波操作直接封神&…...

颚式破碎机的设计

一、引言 颚式破碎机作为矿山、建材等行业的重要破碎设备,其性能优劣直接影响物料破碎效率与质量。随着工业生产规模的扩大和对破碎效率要求的提高,设计一款高效、稳定、节能的颚式破碎机具有重要意义。 二、设计需求分析 处理能力:根据目…...

PH热榜 | 2025-04-18

1. Wiza Monitor 标语:跟踪工作变动,接收Slack和电子邮件的提醒。 介绍:Wiza Monitor是一款用于追踪职位变动的工具,可以实时跟踪客户和潜在客户的工作变动,还可以通过电子邮件和Slack发送提醒,让你的客户…...

Android平台 Hal AIDL 系列文章目录

目录 1. Android Hal AIDL 简介2. AIDL 语言简介3. Android 接口定义语言 (AIDL)4. 定义AIDL 接口5. AIDL 中如何传递 Parcelable 对象6. 如何使用AIDL 定义的远程接口进行跨进程通信7. 适用于 HAL 的 AIDL8. Android Hal AIDL 编译调试9. 高版本Android (AIDL HAL) 沿用HIDL方…...

十、数据库day02--SQL语句01

文章目录 一、新建查询1.查询窗口的开启方法2. 单语句运行方法 二、数据库操作1.创建数据库2. 使用数据库3. 修改数据库4. 删除数据库和查看所有数据库5. 重点:数据库备份5.1 应用场景5.2 利用工具备份备份操作还原操作 5.3 扩展:使用命令备份 三、数据表…...

基于Atlas 800I A2 + Ubuntu 22.04 LTS 离线部署神州鲲泰问学一体机平台

一.环境信息 1.1.硬件信息 Atlas 800I A2 1.2.操作系统 版本: cat /etc/os-release PRETTY_NAME"Ubuntu 22.04 LTS" NAME"Ubuntu" VERSION_ID"22.04" VERSION"22.04 (Jammy Jellyfish)" VERSION_CODENAMEjammy IDubun…...

Shell脚本-变量是什么

在Shell脚本编程中,变量是一个非常基础且重要的概念。它们用于存储数据,并可以在整个脚本中引用这些数据来执行各种操作。理解如何定义、使用和管理变量是编写有效Shell脚本的关键。本文将详细介绍Shell脚本中的变量,包括其基本概念、类型以及…...

MCP 协议:AI 世界的 “USB-C 接口”,开启智能交互新时代

MCP协议:AI世界的“USB-C接口”,开启智能交互新时代 在AI技术飞速发展的今天,不同AI模型、应用与设备之间的交互和协同需求愈发迫切。就像USB-C接口统一了电子设备的数据传输与充电标准一样,**MCP协议(Model Communic…...

服务器的算力已经被被人占用了,我如何能“无缝衔接”?

今天遇到一个问题,服务器已经被别人占用了,我又不知道什么时候他能结束,因此很难去训练自己的模型,隔一会去看看别人是否结束又太麻烦,于是便可以写这个脚本文件来自动检测服务器是否空闲,一有空闲就可以自…...

大数据面试问答-批处理性能优化

1. 数据存储角度 1.1 存储优化 列式存储格式:使用Parquet/ORC代替CSV/JSON,减少I/O并提升压缩率。 df.write.parquet("hdfs://path/output.parquet")列式存储减少I/O的核心机制: 列裁剪(Column Pruning) …...

浅析数据库面试问题

以下是关于数据库的一些常见面试问题: 一、基础问题 什么是数据库? 数据库是按照数据结构来组织、存储和管理数据的仓库。SQL 和 NoSQL 的区别是什么? SQL 是关系型数据库,使用表结构存储数据;NoSQL 是非关系型数据库,支持多种数据模型(如文档型、键值对型等)。什么是…...

Android 12.0 framework实现对系统语言切换的功能实现

1.前言 在12.0的系统rom定制化开发过程中,在定制某些接口的过程中,需要通过系统提供接口,然后实现对系统语言的切换 功能实现,接下来分析下系统中关于系统语言切换的相关功能 2.framework实现对系统语言切换的功能实现的核心类 frameworks/base/core/java/android/app/IA…...

实时直播弹幕系统设计

整个服务读多写少,读写比例大概几百比1. 如果实时性要求高的话,可以采用长连接模式(轮询的话,时效性不好,同时对于评论少的直播间可能空转) websocket 和 SSE架构 只要求服务端推送的话,可以…...

[Java · 初窥门径] Java 语言初识

🌟 想系统化学习 Java 编程?看看这个:[编程基础] Java 学习手册 0x01:Java 编程语言简介 Java 是一种高级计算机编程语言,它是由 Sun Microsystems 公司(已被 Oracle 公司收购)于 1995 年 5 …...

【SQL Server】数据探查工具1.0研发可行性方案

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 想抢先解锁数据自由的宝子,速速戳我!评论区蹲一波 “蹲蹲”,揪人唠唠你的超实用需求! 【SQL Server】数据探查工具1.0研发可行性方案…...

谓词——C++

1.一元谓词 1.定义 2.案例 查找容器有没有大于五的数字 #include<stdio.h> using namespace std; #include<string> #include<vector> #include<set> #include <iostream> class myfind { public:bool operator()(int a){return a > 5;} …...

『前端样式分享』联系我们卡片式布局 自适应屏幕 hover动效 在wikijs中使用 (代码拿来即用)

目录 预览效果分析要点响应式网格布局卡片样式&#xff1a;阴影和过渡效果 代码优化希望 长短不一的邮箱地址在左右居中的同时,做到左侧文字对齐(wikijs可用)总结 欢迎关注 『前端布局样式』 专栏&#xff0c;持续更新中 欢迎关注 『前端布局样式』 专栏&#xff0c;持续更新中…...

Python PDF 转 Markdown 工具库对比与推荐

根据最新评测及开源社区实践&#xff0c;以下为综合性能与适用场景的推荐方案&#xff1a; 1. ‌Marker‌ ‌特点‌&#xff1a; 转换速度快&#xff0c;支持表格、公式&#xff08;转为 LaTeX&#xff09;、图片提取&#xff0c;适配复杂排版文档‌。依赖 PyTorch&#xff0c…...

MySQL 缓存机制全解析:从磁盘 I/O 到性能优化

MySQL 缓存机制全解析&#xff1a;从磁盘 I/O 到性能优化 MySQL 的缓存机制是提升数据库性能的关键部分&#xff0c;它通过多级缓存减少磁盘 I/O 和计算开销&#xff0c;从而提高查询和写入的效率。 1. 为什么需要缓存&#xff1f; 数据库的性能瓶颈通常集中在磁盘 I/O 上。…...

1.1 设置电脑开机自动用户登录exe开机自动启动

本文介绍两个事情&#xff1a; 1.Windows如何开机自动登录系统&#xff08;不用输密码) 2. 应用程序(.exe)如何开机自动启动 详细解释如下&#xff1a; 一、Windows如何开机自动登录系统&#xff08;不用输密码) 设备上的工控机&#xff0c;如果开机后都需要操作人员输入密码&…...

基于 Python 和 OpenCV 技术的疲劳驾驶检测系统(2.0 全新升级,附源码)

大家好&#xff0c;我是徐师兄&#xff0c;一个有着7年大厂经验的程序员&#xff0c;也是一名热衷于分享干货的技术爱好者。平时我在 CSDN、掘金、华为云、阿里云和 InfoQ 等平台分享我的心得体会。 &#x1f345;文末获取源码联系&#x1f345; 2025年最全的计算机软件毕业设计…...

axios 模拟实现

axios 模拟实现 包含发送请求,拦截器,取消请求 第一步 , axios模拟发送请求 //使用 xhr 发送请求function xhr_adpter(config){return new Promise(function handle(resolve,reject){let xhr new XMLHttpRequest();xhr.open(config.method, config.url,true);xhr.onreadysta…...

学术AI工具推荐

一、基础信息对比 维度知网研学AI&#xff08;研学智得AI&#xff09;秘塔AIWOS AI开发公司同方知网&#xff08;CNKI&#xff09;上海秘塔网络科技Clarivate Analytics是否接入DeepSeek✅ 深度集成&#xff08;全功能接入DeepSeek-R1推理服务&#xff09;✅ 通过API接入DeepS…...

OpenAI重返巅峰:o3与o4-mini引领AI推理新时代

引言 2025年4月16日&#xff0c;OpenAI发布了全新的o系列推理模型&#xff1a;o3和o4-mini&#xff0c;这两款模型被官方称为“迎今为止最智能、最强大的大语言模型&#xff08;LLM&#xff09;”。它们不仅在AI推理能力上实现了质的飞跃&#xff0c;更首次具备了全面的工具使…...

Unity3d 6(6000.*.*)版本国区下载安装参考

前言 Unity3d 6.是最新的版本&#xff0c;是与来自世界各地的开发者合作构建、测试和优化的成果&#xff0c;现在可以完全投入生产&#xff0c;是我们迄今为止性能最出色、最稳定的 Unity 版本。Unity 6 有许多令人兴奋的新工具和功能&#xff1a;端到端多人游戏工作流程将加速…...

第 3 期:逆过程建模与神经网络的作用(Reverse Process)

一、从正向扩散到逆向去噪&#xff1a;生成的本质 在上期中我们讲到&#xff0c;正向扩散是一个逐步加入噪声的过程&#xff0c;从原始图像 x_0到接近高斯分布的 x_T​&#xff1a; 而我们真正关心的&#xff0c;是从纯噪声中逐步还原原图的过程&#xff0c;也就是逆过程&…...