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

相关文章

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

Python Excel实现自动添加编号

《PythonExcel实现自动添加编号》这篇文章主要为大家详细介绍了如何使用Python在Excel中实现自动添加编号效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍简单的说,就是在Excel中有一列h=会有重复

Jmeter如何向数据库批量插入数据

《Jmeter如何向数据库批量插入数据》:本文主要介绍Jmeter如何向数据库批量插入数据方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Jmeter向数据库批量插入数据Jmeter向mysql数据库中插入数据的入门操作接下来做一下各个元件的配置总结Jmete

SpringBoot接收JSON类型的参数方式

《SpringBoot接收JSON类型的参数方式》:本文主要介绍SpringBoot接收JSON类型的参数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、jsON二、代码准备三、Apifox操作总结一、JSON在学习前端技术时,我们有讲到过JSON,而在

Spring-AOP-ProceedingJoinPoint的使用详解

《Spring-AOP-ProceedingJoinPoint的使用详解》:本文主要介绍Spring-AOP-ProceedingJoinPoint的使用方式,具有很好的参考价值,希望对大家有所帮... 目录ProceedingJoinPoijsnt简介获取环绕通知方法的相关信息1.proceed()2.g

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Spring MVC跨域问题及解决

《SpringMVC跨域问题及解决》:本文主要介绍SpringMVC跨域问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录跨域问题不同的域同源策略解决方法1.CORS2.jsONP3.局部解决方案4.全局解决方法总结跨域问题不同的域协议、域名、端口

SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

《SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法》本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录方法1:更改IDE配置方法2:在Eclipse中清理项目方法3:使用Maven命令行在开发Sprin

MySQL的隐式锁(Implicit Lock)原理实现

《MySQL的隐式锁(ImplicitLock)原理实现》MySQL的InnoDB存储引擎中隐式锁是一种自动管理的锁,用于保证事务在行级别操作时的数据一致性和安全性,本文主要介绍了MySQL的隐式锁... 目录1. 背景:什么是隐式锁?2. 隐式锁的工作原理3. 隐式锁的类型4. 隐式锁的实现与源代码分析4