SpringBoot定制JSON响应数据的实现

2025-02-10 16:50

本文主要是介绍SpringBoot定制JSON响应数据的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringBoot定制JSON响应数据的实现》本文主要介绍了SpringBoot定制JSON响应数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们...

前言

最近在学习过程中发现http://www.chinasem.cn了Jackson库的@JsonView也可以改变JSON的输出结构,并且可以更加精细的控制,我平时一般都会定义一些DTO去封装响应数据,使用这种方法可以不用创建DTO,更加优雅且高效的方式来实现。

一、如何使用@JsonView这个注解?

我们可以创建多个视图,每个视图代表了一组特定的字段。然后,在控制器的方法上,我们可以通过应用这些视图来指定应该使用哪些字段来序列化返回的实体对象。这种灵活性使得我们能够轻松应对各种复杂的业务需求。

二、应用场景

  • 数据暴露级别的控制

假设你有一个用户实体(User),包含了一些基本信息(如姓名、年龄)和一些敏感信息(如密码、邮箱、身份证)。当你需要提供一个 API 来获取用户的基本信息时,你可能不希望暴露敏感信息。通China编程过使用 @JsonView,你可以定义两个视图:一个包含基本信息,另一个包含所有信息。然后,在对应的 API 方法上,你可以使用相应的视图来控制输出的数据。

  • 根据用户角色定制数据

在某些情况下,不同的用户角色可能需要看到不同级别的数据。例如,管理员可能需要看到用户的所有信息,而普通用户只能看到基本信息。通过使用 @JsonView 和 Spring Security,你可以根据用户的角色来动态地决定应该暴露哪些数据。

  • API 版本控制

当你的 API 随时间发展并引入新功能时,可能会有多个版本的 API。在某些情况下,旧版本的 API 可能不需要包含新引入的字段。通过 @JsonView,你可以为每个 API 版本定义一个视图,并在需要时切换到相应的视图。

  • 数据聚合和拆分

在某些情况下,你可能需要将多个实体的数据聚合到一个 JSON 响应中,或者将一个大实体的数据拆分成多个小实体。通过使用 @JsonView,你可以更轻松地实现这种数据的聚合和拆分。

三、实战案例

定义视图规则:

public interface UserView {
    // 展示基本信息
     interface Basic {}
    // 没有密码
     interface WithoutPassword extends Basic {}
    // 展示所有的信息
     interface Full extends Basic {}
}

定义一个User,在属性上面添加@JSsonView注解,并指定视图

@Data
@AllArgsConstructor
public class User {
    @JsonView(UserView.Basic.class)
    private Long id;
    @JsonView(UserView.Basic.class)
    private String username;
    @JsonView(UserView.Full.class)
    private String password;
    @JsonView(UserView.Basic.class)
    private String nickName;
    @JsonView(UserView.Basic.class)
    private String email;
    @JsonView({UserView.Basic.class,UserView.WithoutPassword.class})
    private String phone;
}

在控制器方法上指定视图,一共有两种方式:注解方式和编程方式。

注解方式

@RestController
public class testController {
    @GetMapping("/user/basic")
    @JsonView(UserView.Basic.class)
    public User userBasic(){
        User user = new User(1L,"admin","123456","小杰不秃头","123456@xx.com","188xxxxxxxx");
        return user;
    }
    @GetMapping("/user/noPassword")
    @JsonView(UserView.WithoutPassword.class)
    public User userNoPassword(){
        User user = new User(1L,"admin","123456","小杰不秃头","123456@xx.com","188xxxxxxxx");
        return user;
    }
    @GetMapping("/user/full")
    @JsonView(UserView.Full.class)
    public User userFull(){
        User user = new User(1L,"admin","123456","小杰不秃头","123456@xx.com","188xxxxxxxx");
        return user;
    }
}

注意:@JsonView允许一个视图类的数组,但你只能为每个控制器方法指定一个。如果需要激活多个视图,可以使用复合接口。

对上面三个接口测试:

//   user/basic
{
  "id": 1,
  "username": "admin",
  "nickName": "小杰不秃头",
  "email": "123456@xx.com",
  "phone": "18编程8xxxxxxxx"
}

//   user/noPassword
{
  "id": 1,
  "username": "admin",
  "nickName": "小杰不秃头",
  "email": "123456@xx.com",
  "phone": "188xxxxxxxx"
}

//   user/full
{
  "id": 1,
  "username": "admin",
  "password": "123456",
  "nickName": "小杰不秃头",
  "email": "123456@xx.com",
  "phone": "188xxxxxxxx"
}

编程方式

@RestController
public class testController {
    @GetMapping("/user/basic")
    //@JsonView(UserVieCBfmHFw.Basic.class)
    public MappingJacksonValue userBasic(){
        User user = new User(1L,"admin","123456","小杰不秃头","123456@xx.com","188xxxxxxxx");
        MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(user);
        mappingJacksonValue.setSerializationView(UserView.Basic.class);
        return mappingJacksonValue;
    }
    @GetMapping("/user/noPassword")
    //@JsonView(UserView.WithoutPassword.class)
    public MappingJacksonValue userNoPassword(){
        User user = new User(1L,"admin","123456","小杰不秃头","123456@xx.com","188xxxxxxxx");
        MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(user);
        mappingJacksonValue.setSerializationView(UserView.WithoutPassword.class);
        return mappingJacksonValue;
    }
    @GetMapping("/user/full")
    //@JsonView(UserView.Full.class)
    public MappingJacksonValue userFull(){
        User user = new User(1L,"admin","123456","小杰不秃头","123456@xx.com","188xxxxxxxx");
        MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(user);
        mappingJacksonValue.setSerializationView(UserView.Full.class);
       China编程 return mappingJacksonValue;
    }
}

//测试结果跟上面一致

注意:接口返回值必须为MappingJacksonValue。

总结 

@JsonView提供了一种灵活且强大的方式来控制序列化的 JSON 数据。通过定义视图和将它们应用到属性和控制器方法上,你可以根据需要暴露不同级别的数据,实现 API 的数据定制化。

@JsonView也可以结合其他的注解一起使用,可以更精细的控制,比如:@JsonInclude、@JsonIgnore等等

到此这篇关于SpringBoot定制JSON响应数据的实现的文章就介绍到这了,更多相关SpringBoot定制响应JSON内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于SpringBoot定制JSON响应数据的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153384

相关文章

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

Java中如何正确的停掉线程

《Java中如何正确的停掉线程》Java通过interrupt()通知线程停止而非强制,确保线程自主处理中断,避免数据损坏,线程池的shutdown()等待任务完成,shutdownNow()强制中断... 目录为什么不强制停止为什么 Java 不提供强制停止线程的能力呢?如何用interrupt停止线程s

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方