SpringBoot使用Jackson序列化返回方式
在Spring Boot應(yīng)用中,使用Jackson庫來處理JSON的序列化和反序列化是一種常見的做法。
Jackson是一個(gè)高效的JSON處理器,廣泛用于Java環(huán)境中,尤其是在與Spring框架集成時(shí)。
本文將詳細(xì)介紹如何在Spring Boot中配置和使用Jackson,以實(shí)現(xiàn)復(fù)雜對象的序列化。
基本配置
在Spring Boot項(xiàng)目中,默認(rèn)已經(jīng)集成了Jackson,因此你不需要手動(dòng)引入Jackson庫。
Spring Boot會(huì)自動(dòng)配置Jackson,并將其用作默認(rèn)的JSON轉(zhuǎn)換庫。
以下是一個(gè)簡單的示例,展示了如何在Spring Boot應(yīng)用中使用Jackson來序列化一個(gè)對象。
實(shí)體類定義
假設(shè)我們有一個(gè)名為User的實(shí)體類,包含幾個(gè)屬性:姓名、年齡和郵箱。
import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
private String name;
private int age;
private String email;
// 標(biāo)準(zhǔn)的getter和setter
public 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控制器中,你可以直接返回一個(gè)對象,Spring MVC會(huì)自動(dòng)使用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的默認(rèn)配置通常足夠使用,但在某些情況下,你可能需要對Jackson的行為進(jìn)行定制。以下是一些常見的自定義配置方法。
簡單使用
如果你想要自定義某個(gè)類的序列化方式,可以通過實(shí)現(xiàn)JsonSerializer來實(shí)現(xiàn)。
例如,如果你想在序列化User類時(shí)隱藏郵箱信息,可以創(chuàng)建一個(gè)自定義的序列化器。
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);
}
@Override
public 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();
}
}
整數(shù)格式化為千分位
在使用 Jackson 進(jìn)行序列化時(shí),如果需要將整數(shù)(例如 Integer 類型)格式化為帶有千分位的字符串(如 “100,000”),可以通過自定義序列化器來實(shí)現(xiàn)。
這里我將演示如何創(chuàng)建一個(gè)自定義的序列化器,并應(yīng)用在一個(gè)實(shí)體類的字段上。
步驟 1: 創(chuàng)建自定義序列化器
首先,我們需要?jiǎng)?chuàng)建一個(gè)擴(kuò)展自 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("#,###");
@Override
public void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value == null) {
gen.writeNull();
} else {
gen.writeString(formatter.format(value));
}
}
}
這個(gè)自定義的序列化器使用 DecimalFormat 將整數(shù)格式化為千分位字符串。
步驟 2: 應(yīng)用注解到實(shí)體類
現(xiàn)在,你可以使用 @JsonSerialize 注解來指定使用這個(gè)自定義序列化器。
將此注解添加到實(shí)體類的相應(yīng)字段上:
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class DataModel {
private String name;
@JsonSerialize(using = ThousandsFormatterSerializer.class)
private Integer amount;
// 構(gòu)造函數(shù)、getter 和 setter 省略
}
在這個(gè)例子中,amount 字段將被格式化為千分位字符串,當(dāng) Jackson 序列化這個(gè) DataModel 類的實(shí)例時(shí)。
步驟 3: 使用和測試
最后,在你的應(yīng)用程序中創(chuàng)建 DataModel 的實(shí)例,并通過 Spring Boot 的 REST 控制器返回它,Jackson 會(huì)自動(dòng)應(yīng)用這個(gè)自定義的序列化器來格式化 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;
}
}
當(dāng)你訪問這個(gè)控制器方法時(shí),你應(yīng)該會(huì)看到如下格式的 JSON 響應(yīng):
{
"name": "Example",
"amount": "100,000"
}
幾個(gè)常用的注解
指定序列化和反序列化時(shí)JSON對象的屬性名。@JsonProperty
- 指定序列化和反序列化時(shí)JSON對象的屬性名。
- 例如,可以將Java字段名從
firstName映射到 JSON 屬性first_name。
public class User {
@JsonProperty("first_name")
private String firstName;
}
在序列化和反序列化過程中忽略該屬性。@JsonIgnore
在序列化和反序列化過程中忽略該屬性。
public class User {
private String firstName;
@JsonIgnore
private String password;
}
用于格式化字段,如日期格式。@JsonFormat
用于格式化字段,如日期格式。
public class User {
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date birthDate;
}
下面有詳細(xì)講
使用@JsonView控制輸出
@JsonView 是Jackson提供的一種方式,允許你在同一個(gè)類中定義多個(gè)視圖,根據(jù)上下文來序列化不同的屬性集合。
這個(gè)功能在你需要根據(jù)用戶的不同權(quán)限展示不同級別的數(shù)據(jù)時(shí)特別有用。
定義視圖
首先,你需要定義一些視圖接口。
這些接口不包含任何方法,它們的目的是為不同的序列化視圖提供標(biāo)記。
public class Views {
public static class Public {}
public static class Internal extends Public {}
}
應(yīng)用視圖到實(shí)體類
然后,使用@JsonView注解來標(biāo)注User實(shí)體類中的不同字段,這些字段將根據(jù)視圖的不同而序列化。
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注解來指定哪個(gè)視圖應(yīng)該被用于序列化。
@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;
}
}
@JsonView和JsonSerializer混合使用
在Jackson中,@JsonView 和 JsonSerializer 是可以組合使用的,但這樣做可能會(huì)導(dǎo)致一些復(fù)雜性和冗余。
這兩種機(jī)制都用于控制JSON序列化的行為,但它們各自適用于不同的場景。
使用場景
@JsonView:這是一種較為簡潔的方法,用于在不同的上下文中控制哪些屬性被包含在JSON中。它適用于簡單的情況,比如當(dāng)同一個(gè)對象在不同的API端點(diǎn)返回不同字段時(shí)。JsonSerializer:這是一個(gè)更為強(qiáng)大和靈活的工具,允許你完全控制一個(gè)對象的序列化過程。當(dāng)你需要對序列化進(jìn)行詳細(xì)控制,如改變輸出的結(jié)構(gòu)或添加復(fù)雜的條件邏輯時(shí),這是一個(gè)更好的選擇。
組合使用
當(dāng)你同時(shí)使用@JsonView和JsonSerializer時(shí),通常是因?yàn)槟阈枰幚矸浅>唧w的序列化需求,如下面的示例所示:
public class CustomUserSerializer extends StdSerializer<User> {
public CustomUserSerializer() {
super(User.class);
}
@Override
public 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();
}
}
在這個(gè)例子中,CustomUserSerializer 判斷當(dāng)前激活的視圖,并根據(jù)視圖決定序列化哪些字段。這樣做雖然增加了靈活性,但也增加了代碼的復(fù)雜性和維護(hù)難度。
處理日期和枚舉
處理日期和枚舉類型時(shí),可能需要特別注意。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
}
枚舉的自定義序列化
對于枚舉類型,你可能想要序列化為不同于默認(rèn)的名字。使用@JsonValue注解可以指定一個(gè)枚舉的方法來返回想要序列化的值。
public enum Type {
FULL_TIME("Full time"),
PART_TIME("Part time");
private String value;
Type(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}
### 返回結(jié)果示例
假設(shè)你有一個(gè)Java類`Employee`,其中包含一個(gè)`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應(yīng)用中,當(dāng)你返回一個(gè)包含枚舉字段的Employee對象時(shí),由于Type枚舉使用了@JsonValue,序列化的JSON將反映getValue()方法提供的字符串,而不是枚舉的名字。
例如:
@RestController
public class EmployeeController {
@GetMapping("/employee")
public Employee getEmployee() {
return new Employee("張三", Type.FULL_TIME);
}
}
該端點(diǎn)返回的JSON可能如下所示:
{
"name": "張三",
"employmentType": "Full time"
}
這里,employmentType字段顯示為"Full time",這是FULL_TIME枚舉值的自定義序列化輸出。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用Java找出兩個(gè)List中的重復(fù)元素三種方法
在Java編程中,我們經(jīng)常需要找出兩個(gè)列表(List)中的重復(fù)元素,在本文中,我們將探討三種方法來實(shí)現(xiàn)這一目標(biāo),需要的朋友可以參考下2023-10-10
mybatis類型處理器JSR310標(biāo)準(zhǔn)詳解
這篇文章主要介紹了mybatis類型處理器JSR310標(biāo)準(zhǔn)詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringBoot項(xiàng)目統(tǒng)一枚舉轉(zhuǎn)換實(shí)踐過程
文章介紹了在Spring Boot項(xiàng)目中統(tǒng)一枚舉轉(zhuǎn)換的實(shí)踐,通過使用自定義的父枚舉接口和AttributeConverter、ConverterFactory、JsonSerializer和JsonDeserializer等工具,實(shí)現(xiàn)了枚舉與數(shù)據(jù)庫、請求參數(shù)、響應(yīng)參數(shù)和消息參數(shù)之間的自動(dòng)轉(zhuǎn)換2024-12-12
MyBatis中執(zhí)行相關(guān)SQL語句的方法
本文主要介紹了MyBatis中執(zhí)行相關(guān)SQL語句的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
基于SpringBoot實(shí)現(xiàn)郵箱找回密碼的代碼示例
本文主要介紹了如何基于SpringBoot實(shí)現(xiàn)郵箱找回密碼,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-02-02
springboot使用校驗(yàn)框架validation校驗(yàn)的示例
這篇文章主要介紹了springboot使用校驗(yàn)框架validation校驗(yàn)的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02

