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.mzph.cn/diannao/515.shtml

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

相关文章

ubuntu18.04安装F4PGA教程

环境搭建教程&#xff1a; f4pga-arch-defs/xilinx/xc7 at main f4pga/f4pga-arch-defs GitHub git clone https://github.com/SymbiFlow/f4pga-arch-defs.git cd f4pga-arch-defs make env cd build 主要是make env&#xff0c;会下载很多东西&#xff0c;然后生成很多描…

数据结构·一篇搞定顺序表!

大家好啊&#xff0c;几日不见&#xff0c;甚是想念&#xff0c;从这一篇文章开始&#xff0c;我们就要进入数据结构了哦&#xff0c;那么我们废话不多说&#xff0c;今天我们一起来搞定顺序表&#xff01;&#xff01;&#xff01; 1. 顺序表概念及结构 顺序表是一种线性结…

VBA脚本终章编译器崩溃

一、介绍 本篇文章为VBA脚本隐藏技术的最后一篇&#xff0c;将介绍如何在保证VBA脚本正常执行的情况下&#xff0c;使分析人员无法打开编译器。 那么为什么需要分析人员无法打开编译器呢&#xff1f; 首先&#xff0c;我们需要引入一个知识点。 在上篇《VBA隐藏技术stompin…

系统思考—战略

“有策略而无战术&#xff0c;是取胜之最慢之道。有战术而无策略&#xff0c;是败亡之前的嘈杂。”—孙子 最近接触的中小企业&#xff0c;充分能感受到在经济下行的情况下&#xff0c;组织与战略是不可分割的两个方面。有时候公司组织出现了问题&#xff0c;可能是因为战略不…

maven3.9的settings.xml 内容学习

settings.xml 文件介绍 settings.xml 是 Maven 的配置文件&#xff0c;它允许你自定义 Maven 的行为&#xff0c;比如设置仓库、代理、认证信息等。在 Maven 3.9 中&#xff0c;settings.xml 的结构和内容可能与之前的版本相似&#xff0c;但可能会有一些小的改进或变化。下面…

单分支:if语句

示例&#xff1a; /*** brief how about if? show you here.* author wenxuanpei* email 15873152445163.com(query for any question here)*/ #define _CRT_SECURE_NO_WARNINGS//support c-library in Microsoft-Visual-Studio #include <stdio.h>#define if_state…

MoJoCo 入门教程(七)XML 参考

系列文章目录 前言 表格第二列中的符号含义如下&#xff1a; ! 必填元素&#xff0c;只能出现一次 ? 可选元素&#xff0c;只能出现一次 * 可选元素&#xff0c;可多次出现 R 可选元素&#xff0c;可递归出现多次 一、简介 本章是 MuJoCo 中使用的 MJCF 建模语言的参考手册。…

【投稿优惠|稳定检索】2024年低碳发展与地球科学国际会议 (LCDES 2024)

2024年低碳发展与地球科学国际会议 (LCDES 2024) 2024 International Conference on Low Carbon Development and Earth Science 【会议简介】 2024年低碳发展与地球科学国际会议即将在长沙盛大召开。本次会议将汇聚全球低碳发展与地球科学领域的专家学者&#xff0c;共同探讨…

登录解析(前端)

登录代码 1、登录之后做了什么&#xff1f; 执行登陆方法&#xff0c;成功之后&#xff0c;路由跳转到指定路径或者根目录 2、this.$store.dispatch是什么意思&#xff1f; this.$store.dispatch(‘Login’, this.loginForm) 来调取store里的user.js的login方法3、this.$r…

将MySQL数据库导入到EA模型的教程

将MySQL数据库导入到EA 1.下载安装mysql-connector-odbc2.在管理工具中新增ODBC数据源3.在EA中新建项目4.链接MYSQL数据源4.1 安装64位的ODBC驱动可能出现”在连接ODBC 时发生错误&#xff0c;请相关检查设置“的提示&#xff0c;卸载后重新安装32位ODBC驱动后可以正常执行 5.导…

智慧园区引领产业智能化升级:科技创新驱动打造智慧化、高效化产业新未来

随着全球科技革命的深入推进&#xff0c;以大数据、云计算、物联网、人工智能等为代表的新一代信息技术正深刻改变着传统产业的发展模式。在这一背景下&#xff0c;智慧园区作为产业智能化升级的重要载体和平台&#xff0c;正以其前瞻性的规划、创新的科技和卓越的实践&#xf…

OpenCV杂记(2):图像拼接(hconcat, vconcat)

OpenCV杂记&#xff08;1&#xff09;&#xff1a;绘制OSD&#xff08;cv::getTextSize, cv::putText&#xff09;https://blog.csdn.net/tecsai/article/details/137872058 1. 简述 做图像处理或计算机视觉技术的同学都知道&#xff0c;我们在工作中会经常遇到需要将两幅图像拼…

IntelliJ-platform plugIn 插件开发专题内容介绍,学习指导(一)

这系列文章出炉对于笔者来说确实不容易&#xff0c;历时快两年了&#xff0c;先后迭代了3版本&#xff0c;暂时与官方最新版本API同步&#xff08;2024.03&#xff09;&#xff0c;文章内容覆盖2022~2024版内容 专题由来 最早接触插件开发是源于公司一个国际化项目&#xff0c…

以pytorch pipeline并行为例,分析各kernel的耗时占比及性能瓶颈

以pytorch pipeline并行为例,分析各kernel的耗时占比及性能瓶颈 1.生成pipeline并行的测试代码2.pipeline profing3.生成nsys2json.py代码4.将nsys sqlite格式转chrome json格式5.生成耗时成分统计代码6.统计耗时成分7.耗时成分如下:8.查看GPU PCIE链路状态9.链路状态如下10.Ns…

Unity地形关联出错的解决办法以及地形深度拷贝

问题 最近发现unity地形系统的一个bug&#xff0c;导入的场景地形数据关联错乱了&#xff0c;关联到别的场景的地形数据了&#xff0c;meta替换了也没用&#xff0c;不清楚它具体是怎么关联的。 看下面的案例&#xff1a; 可以看到正常这个场景的地形数据应该关联的是Scene_E…

gma 2 用户文档(pdf版)更新计划

随着 gma 2 整体构建完成&#xff0c;下一步继续针对库内所有功能完成一个用户指南&#xff08;非网站&#xff09;。相较于上次更新用户文档pdf版&#xff0c;已经过去了大半年。当然&#xff0c;PDF 版比网站上内容更丰富&#xff0c;也更新&#xff08;文档基于 gma 2.0.9a2…

【Java】集合概念及多线程

HashSet 、 LinkedHashSet 和 TreeSet 的主要区别在于底层数据结构不同。 HashSet 的底层数据结构是哈希表&#xff08;基于 HashMap 实现&#xff09;。 LinkedHashSet 的底层数据结构是链表和哈希表&#xff0c;元素的插⼊和取出顺序满⾜ FIFO。 TreeSet 底层数据结构是红…

Linux系统下使用Parted调整物理分区大小

前言 在管理Linux系统时&#xff0c;有时需要对物理分区大小进行调整以满足不断变化的需求。Parted是一款功能强大的分区管理工具&#xff0c;可以帮助您轻松地进行这项任务。本文将简要介绍如何使用Parted来调整物理分区大小&#xff0c;让您能够快速且安全地完成这一操作。 …

【前端】4. CSS综合案例

1. 模拟新闻界面 <!-- 1.模拟实现新闻界面 --><!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…

YMP实现Oracle迁移到YashanDB

迁移需求 ip地址 数据库信息 操作系统信息 源库 192.168.3.132 实例名topdh 用户密码TOPICIS/oracle 端口1521 Centos7.9 x86_64 目标库 192.168.3.175 实例名yasdb 用户密码topicist/opicis 端口1688 Centos7.9 x86_64 迁移前准备 YMP工具获取 根据实际需求向厂…