SpringBoot中使用Jackson序列化返回

SpringBoot中使用Jackson序列化返回

在Spring Boot应用中,使用Jackson库来处理JSON的序列化和反序列化是一种常见的做法。Jackson是一个高效的JSON处理器,广泛用于Java环境中,尤其是在与Spring框架集成时。本文将详细介绍如何在Spring Boot中配置和使用Jackson,以实现复杂对象的序列化。

基本配置

在Spring Boot项目中,默认已经集成了Jackson,因此你不需要手动引入Jackson库。Spring Boot会自动配置Jackson,并将其用作默认的JSON转换库。以下是一个简单的示例,展示了如何在Spring Boot应用中使用Jackson来序列化一个对象。

实体类定义

假设我们有一个名为User的实体类,包含几个属性:姓名、年龄和邮箱。

import com.fasterxml.jackson.annotation.JsonProperty;public class User {private String name;private int age;private String email;// 标准的getter和setterpublic String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}
}

控制器层

在Spring Boot控制器中,你可以直接返回一个对象,Spring MVC会自动使用Jackson将对象序列化为JSON格式。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@GetMapping("/user")public User getUser() {User user = new User();user.setName("张三");user.setAge(30);user.setEmail("zhangsan@example.com");return user;}
}

自定义序列化,JsonSerializer

尽管Spring Boot的默认配置通常足够使用,但在某些情况下,你可能需要对Jackson的行为进行定制。以下是一些常见的自定义配置方法。

简单使用

如果你想要自定义某个类的序列化方式,可以通过实现JsonSerializer来实现。例如,如果你想在序列化User类时隐藏邮箱信息,可以创建一个自定义的序列化器。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;import java.io.IOException;public class UserSerializer extends StdSerializer<User> {public UserSerializer() {this(null);}public UserSerializer(Class<User> t) {super(t);}@Overridepublic void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {jsonGenerator.writeStartObject();jsonGenerator.writeStringField("name", user.getName());jsonGenerator.writeNumberField("age", user.getAge());// 不序列化email字段jsonGenerator.writeEndObject();}
}

整数格式化为千分位

在使用 Jackson 进行序列化时,如果需要将整数(例如 Integer 类型)格式化为带有千分位的字符串(如 “100,000”),可以通过自定义序列化器来实现。这里我将演示如何创建一个自定义的序列化器,并应用在一个实体类的字段上。

步骤 1: 创建自定义序列化器

首先,我们需要创建一个扩展自 JsonSerializer<T> 的类,专门用于序列化 Integer 字段。

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.text.DecimalFormat;public class ThousandsFormatterSerializer extends JsonSerializer<Integer> {private static final DecimalFormat formatter = new DecimalFormat("#,###");@Overridepublic void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers) throws IOException {if (value == null) {gen.writeNull();} else {gen.writeString(formatter.format(value));}}
}

这个自定义的序列化器使用 DecimalFormat 将整数格式化为千分位字符串。

步骤 2: 应用注解到实体类

现在,你可以使用 @JsonSerialize 注解来指定使用这个自定义序列化器。将此注解添加到实体类的相应字段上:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;public class DataModel {private String name;@JsonSerialize(using = ThousandsFormatterSerializer.class)private Integer amount;// 构造函数、getter 和 setter 省略
}

在这个例子中,amount 字段将被格式化为千分位字符串,当 Jackson 序列化这个 DataModel 类的实例时。

步骤 3: 使用和测试

最后,在你的应用程序中创建 DataModel 的实例,并通过 Spring Boot 的 REST 控制器返回它,Jackson 会自动应用这个自定义的序列化器来格式化 amount 字段。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DataController {@GetMapping("/formatted-data")public DataModel getFormattedData() {DataModel data = new DataModel();data.setName("Example");data.setAmount(100000);return data;}
}

当你访问这个控制器方法时,你应该会看到如下格式的 JSON 响应:

{"name": "Example","amount": "100,000"
}

几个常用的注解

指定序列化和反序列化时JSON对象的属性名。@JsonProperty

  • 指定序列化和反序列化时JSON对象的属性名。
  • 例如,可以将Java字段名从 firstName 映射到 JSON 属性 first_name
public class User {@JsonProperty("first_name")private String firstName;
}

在序列化和反序列化过程中忽略该属性。@JsonIgnore

在序列化和反序列化过程中忽略该属性。

public class User {private String firstName;@JsonIgnoreprivate String password;
}

用于格式化字段,如日期格式。 @JsonFormat

用于格式化字段,如日期格式。

public class User {@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")private Date birthDate;
}

下面有详细讲

使用@JsonView控制输出

@JsonView 是Jackson提供的一种方式,允许你在同一个类中定义多个视图,根据上下文来序列化不同的属性集合。这个功能在你需要根据用户的不同权限展示不同级别的数据时特别有用。

定义视图

首先,你需要定义一些视图接口。这些接口不包含任何方法,它们的目的是为不同的序列化视图提供标记。

public class Views {public static class Public {}public static class Internal extends Public {}
}

应用视图到实体类

然后,使用@JsonView注解来标注User实体类中的不同字段,这些字段将根据视图的不同而序列化。

public class User {@JsonView(Views.Public.class)private String name;@JsonView(Views.Public.class)private int age;@JsonView(Views.Internal.class)private String email;// getters 和 setters
}

控制器中使用视图

在Spring MVC控制器中,你可以通过@JsonView注解来指定哪个视图应该被用于序列化。

@RestController
public class UserController {@GetMapping("/user/public")@JsonView(Views.Public.class)public User getPublicUser() {return createUser();}@GetMapping("/user/internal")@JsonView(Views.Internal.class)public User getInternalUser() {return createUser();}private User createUser() {User user = new User();user.setName("张三");user.setAge(30);user.setEmail("zhangsan@example.com");return user;}
}

@JsonViewJsonSerializer 混合使用

在Jackson中,@JsonViewJsonSerializer 是可以组合使用的,但这样做可能会导致一些复杂性和冗余。这两种机制都用于控制JSON序列化的行为,但它们各自适用于不同的场景。

使用场景

  1. @JsonView:这是一种较为简洁的方法,用于在不同的上下文中控制哪些属性被包含在JSON中。它适用于简单的情况,比如当同一个对象在不同的API端点返回不同字段时。

  2. JsonSerializer:这是一个更为强大和灵活的工具,允许你完全控制一个对象的序列化过程。当你需要对序列化进行详细控制,如改变输出的结构或添加复杂的条件逻辑时,这是一个更好的选择。

组合使用

当你同时使用@JsonViewJsonSerializer时,通常是因为你需要处理非常具体的序列化需求,如下面的示例所示:

public class CustomUserSerializer extends StdSerializer<User> {public CustomUserSerializer() {super(User.class);}@Overridepublic void serialize(User user, JsonGenerator gen, SerializerProvider provider) throws IOException {gen.writeStartObject();if (provider.getActiveView() != null && provider.getActiveView().equals(Views.Public.class)) {gen.writeStringField("name", user.getName());}if (provider.getActiveView() != null && provider.getActiveView().equals(Views.Internal.class)) {gen.writeStringField("email", user.getEmail());gen.writeNumberField("age", user.getAge());}gen.writeEndObject();}
}

在这个例子中,CustomUserSerializer 判断当前激活的视图,并根据视图决定序列化哪些字段。这样做虽然增加了灵活性,但也增加了代码的复杂性和维护难度。

处理日期和枚举

处理日期和枚举类型时,可能需要特别注意。Jackson提供了多种方式来定制日期和枚举的序列化方式。

日期格式化

如果你需要自定义日期的格式,可以使用@JsonFormat注解来指定日期字段的格式。

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;public class Event {private String name;@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")private Date eventDate;// getters 和 setters
}

枚举的自定义序列化

对于枚举类型,你可能想要序列化为不同于默认的名字。使用@JsonValue注解可以指定一个枚举的方法来返回想要序列化的值。

public enum Type {FULL_TIME("Full time"),PART_TIME("Part time");private String value;Type(String value) {this.value = value;}@JsonValuepublic String getValue() {return value;}
}### 返回结果示例假设你有一个Java类`Employee`,其中包含一个`Type`枚举字段,如下所示:```java
public class Employee {private String name;private Type employmentType;public Employee(String name, Type employmentType) {this.name = name;this.employmentType = employmentType;}// Getters and Setters
}

在Spring Boot应用中,当你返回一个包含枚举字段的Employee对象时,由于Type枚举使用了@JsonValue,序列化的JSON将反映getValue()方法提供的字符串,而不是枚举的名字。例如:

@RestController
public class EmployeeController {@GetMapping("/employee")public Employee getEmployee() {return new Employee("张三", Type.FULL_TIME);}
}

该端点返回的JSON可能如下所示:

{"name": "张三","employmentType": "Full time"
}

这里,employmentType字段显示为"Full time",这是FULL_TIME枚举值的自定义序列化输出。

参考链接

  • 官方Spring文档关于JSON处理:https://spring.io/projects/spring-framework#overview
  • Jackson项目主页:https://github.com/FasterXML/jackson
  • 关于Jackson注解的详细使用:https://www.baeldung.com/jackson
  • 更多关于@JsonView的用法:https://www.baeldung.com/jackson-json-view-annotation

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB数据类型和运算符+矩阵创建

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍一、MATLAB数据类型和运算符&#x1f48e;1 MATLAB的数据类型&#x1f339;…

LeetCode 24. 两两交换链表中的节点

解题思路 这道题用画图的方法是比较好的。 相关代码 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.…

C语言输出不同颜色的字体

本文章在Linux进行演示&#xff01;&#xff01;&#xff01; 使用C语言输出不同颜色字体和背景 格式&#xff1a; printf("\033[字体背景颜色;字体颜色m字符串\033[0m"); 上边的 \033 也可以用 \e 来代替。 字体颜色与字符的对应关系 字符颜色30黑色31红…

经验分享:云知识库才是智能时代企业的最优选择

我知道你们可能会有点困惑&#xff0c;云知识库是什么&#xff1f;为什么它会是智能时代企业的最优选择&#xff1f;不要紧张&#xff0c;坐稳了&#xff0c;我带你们慢慢了解这个鲜为人知的神器。 首先&#xff0c;让我们说说什么是"云知识库"。云知识库就像一个在线…

uniapp APP真机调试接口请求不到服务器解决方法

项目场景&#xff1a; 在使用Hbuilder开发uniapp的过程中&#xff0c;出现了两个在 Chrome 调试中正常&#xff0c;但打包后异常的问题&#xff0c;特此记录。 问题描述 在 H5 端请求接口正常请求。 App 端 请求接口&#xff0c;提示 "{"errMsg":"reque…

常见的垃圾回收器(下)

文章目录 G1ShenandoahZGC 常见垃圾回收期&#xff08;上&#xff09; G1 参数1&#xff1a; -XX:UseG1GC 打开G1的开关&#xff0c;JDK9之后默认不需要打开 参数2&#xff1a;-XX:MaxGCPauseMillis毫秒值 最大暂停的时间 回收年代和算法 ● 年轻代老年代 ● 复制算法 优点…

常见的垃圾回收算法

文章目录 1. 标记清除算法2. 复制算法3. 标记整理算法4. 分代垃圾回收算法 1. 标记清除算法 核心思想&#xff1a; 标记阶段&#xff0c;将所有存活的对象进行标记。Java中使用可达性分析算法&#xff0c;从GC Root开始通过引用链遍历出所有存活对象。清除阶段&#xff0c;从…

如何使用 ArcGIS Pro 制作热力图

热力图是一种用颜色表示数据密度的地图&#xff0c;通常用来显示空间分布数据的热度或密度&#xff0c;我们可以通过 ArcGIS Pro 来制作热力图&#xff0c;这里为大家介绍一下制作的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数…

不得不掌握的性能测试监控神器 -nmon 工具详解

做性能测试时候进行结果收集和监控是我们必须要进行的一个步骤&#xff0c;所以选择一个好的监控工具能帮我们省事省心。我们今天给大家介绍的监听工具nmon&#xff0c;就是一个非常强大而且市场上也非常主流应用的一个监控工具。 做性能测试时候进行结果收集和监控是我们必须要…

vox2vec论文速读

vox2vec: A Framework for Self-supervised Contrastive Learning of Voxel-Level Representations in Medical Images 摘要 本文介绍了 vox2vec——一种体素级表示的自监督学习 &#xff08;SSL&#xff09; 对比方法 vox2vec 表示由特征金字塔网络 &#xff08;FPN&#xf…

设计模式-外观模式(Facade)

1. 概念 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它提供了一个统一的接口&#xff0c;用于访问子系统中的一群接口。外观模式的主要目的是隐藏系统的复杂性&#xff0c;通过定义一个高层级的接口&#xff0c;使得子系统更容易被使用。…

如何在前后端一体的项目中引入element-ui,即引入index.js、index.css等文件。

24年接手了一个18年的项目&#xff0c;想使用el-ui的组件库&#xff0c;得自己手动引入。 通过官网可以知道&#xff0c;首先得准备以下文件 <!-- 引入样式 --> <link rel"stylesheet" href"https://unpkg.com/element-ui/lib/theme-chalk/index.css…