知識庫 / JSON / Jackson RSS 訂閱

Jackson 中 @JsonFormat 指南

Data,Jackson
HongKong
6
09:56 PM · Dec 05 ,2025

1. 概述

在本教程中,我們將學習如何在 Jackson 中使用 @JsonFormat

@JsonFormat 是 Jackson 中的一個註解,它允許我們配置屬性值的序列化或反序列化方式。例如,我們可以指定如何根據 SimpleDateFormat 格式來格式化 DateCalendar 值。

2. Maven 依賴

<em @JsonFormat</em>jackson-databind 包中定義,因此我們需要以下 Maven 依賴:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.2</version>
</dependency>

3. Getting Started

This section provides a basic introduction to the system. It covers the initial setup, installation process, and a simple example to get you started.

3.1 Installation

  1. Download the latest version of the software from our website: https://www.example.com/download
  2. Extract the downloaded archive to a directory of your choice.
  3. Run the setup.exe file to begin the installation process. Follow the on-screen instructions.

3.2 First Steps

  1. Launch the application from the Start Menu or Desktop shortcut.
  2. The first time you run the application, you will be prompted to create a new project.
  3. Choose a project name and location.

3.3 Simple Example

# This is a simple Python script to print "Hello, World!"
print("Hello, World!")

3.1. 使用默認格式

我們將首先演示使用 <em @JsonFormat</em> 註解的概念,以一個表示用户的類為例。

由於我們希望詳細解釋註解的細節,因此 User 對象將在請求時創建(不存儲或從數據庫加載),並將其序列化為 JSON:

public class User {
    private String firstName;
    private String lastName;
    private Date createdDate = new Date();

    // standard constructor, setters and getters
}

構建並運行此代碼示例將返回以下輸出:

{"firstName":"John","lastName":"Smith","createdDate":1482047026009}

如我們所見,createdDate 字段顯示為自紀元以來的毫秒數,這是 Date 字段的默認格式。

3.2. 使用 Getter 註解

我們將使用 <em @JsonFormat</em> 來指定序列化 <em createdDate</em> 字段的格式。

讓我們看一下 User 類針對此更改所做的更新。 我們通過註解 <em createdDate</em> 字段,如所示,來指定日期格式。

用於 <em pattern</em> 參數的數據格式由 <em <a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/text/SimpleDateFormat.html">SimpleDateFormat</a></em> 規範。

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ")
private Date createdDate;

實施此更改後,我們重新構建項目並運行它。

以下是輸出:

{"firstName":"John","lastName":"Smith","createdDate":"2016-12-18@07:53:34.740+0000"}

我們使用指定的 SimpleDateFormat 格式來格式化 createdDate 字段,使用了 @JsonFormat 註解。

上述示例演示了在字段上使用註解的方法。我們也可以將其用於 getter 方法(屬性)。

例如,我們可能有一個在調用時計算的屬性。在這種情況下,我們可以將註解用於該 getter 方法。

請注意,我們還更改了模式以僅返回瞬時的時間部分:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
public Date getCurrentDate() {
    return new Date();
}

以下是輸出結果:

{ ... , "currentDate":"2016-12-18", ...}

3.3. 指定區域設置

除了指定日期格式,我們還可以指定序列化的區域設置。

未指定此參數將導致使用默認區域設置進行序列化:

@JsonFormat(
  shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ", locale = "en_GB")
public Date getCurrentDate() {
    return new Date();
}

3.4. 指定形狀

使用 @JsonFormat,並將 shape 設置為 JsonFormat.Shape.NUMBER,將產生對 Date 類型默認輸出——自紀元以來(以毫秒為單位)的數值。

pattern 參數在此情況下不適用且將被忽略:

@JsonFormat(shape = JsonFormat.Shape.NUMBER)
public Date getDateNum() {
    return new Date();
}

讓我們來看一下輸出:

{ ..., "dateNum":1482054723876 }

4. 不區分大小寫的反序列化

有時,我們從各種來源接收到 JSON 文檔,這些文檔在屬性名稱的大小寫規則上不一致。例如,一個 JSON 文檔包含 “firstname”: “John”,而其他文檔可能包含 “firstName”: “John” 或 “FIRSTNAME”: “John”

默認的反序列化器無法自動識別不同大小寫字母的屬性名稱。讓我們通過一個例子快速理解這個問題。

首先,假設我們有以下 JSON 文檔作為輸入:

static final String JSON_STRING = "{\"FIRSTNAME\":\"John\",\"lastname\":\"Smith\",\"cReAtEdDaTe\":\"2016-12-18@07:53:34.740+0000\"}";

如我們所見,三個屬性“FIRSTNAME”、“lastname”和“cReAtEdDaTe”完全遵循不同的大小寫規則。現在,如果我們將此JSON文檔反序列化為User對象,將會拋出UnrecognizedPropertyException

assertThatThrownBy(() -> new ObjectMapper().readValue(JSON_STRING, User.class)).isInstanceOf(UnrecognizedPropertyException.class);

如上測試所示,我們使用了 Assertj 的異常斷言來驗證預期異常是否被拋出。

為了解決此類問題,我們必須使我們的反序列器執行不區分大小寫的反序列化

因此,接下來我們來探討如何使用 @JsonFormat 註解來實現這一點。

@JsonFormat 註解允許我們通過 with 屬性設置一組 JsonFormat.Feature@JsonFormat(with = JsonFormat.Feature … ).

JsonFormat.Feature 是一種枚舉。它預定義了一組選項,用於指定屬性序列化或反序列化行為。

ACCEPT_CASE_INSENSITIVE_PROPERTIES 特性告訴反序列器匹配屬性名稱時不區分大小寫。要使用此特性,我們可以將其包含在類級別的 @JsonFormat 註解中。

接下來,讓我們創建一個 UserIgnoreCase 類,其中包含此註解和特性:

@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
class UserIgnoreCase {
    private String firstName;
    private String lastName;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ")
    private Date createdDate;

    // the rest is the same as the User class
    ...
};

現在,如果我們將我們的 JSON 輸入反序列化到 UserIgnoreCase,它將按預期工作:

UserIgnoreCase result = new ObjectMapper().readValue(JSON_STRING, UserIgnoreCase.class);
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSzz");
Date expectedDate = fmt.parse("2016-12-18T07:53:34.740+0000");
assertThat(result)
  .isNotNull()
  .returns("John", from(UserIgnoreCase::getFirstName))
  .returns("Smith", from(UserIgnoreCase::getLastName))
  .returns(expectedDate, from(UserIgnoreCase::getCreatedDate));

值得一提的是,我們使用了 Assertj 的 returns()from() 方法來在一個單一斷言中驗證多個屬性。這非常方便,並且使代碼更易於閲讀。

5. 結論

總而言之,我們使用 @JsonFormat 來控制 DateCalendar 類型的數據輸出格式。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.