Jackson 泛型類型反序列化

Jackson
Remote
0
08:34 PM · Nov 30 ,2025

1. 背景

Jackson 是一個流行的 Java 庫,用於將 Java 對象序列化為 JSON 和反序列化為 JSON。在某些情況下,Java 對象可以被定義為具有泛型類型。

在本教程中,我們將演示如何使用 Jackson 將 JSON 字符串反序列化為泛型類型。

2. 模型準備

對於提供的JSON字符串進行反序列化:

{"result":{"id":1,"firstName":"John","lastName":"Lewis"}}

我們需要定義一個具有泛型類型參數和常規POJO對象來存儲數據:

public class JsonResponse<T> {
    private T result;

    // getters and setters...
}
public class User {
    private Long id;
    private String firstName;
    private String lastName;

    // getters and setters...
}

3. Deserialize Generic Type

在 Jackson 中,ObjectMapper 提供了三個用於 JSON 反序列化的 readValue 方法集,它們接受:

  • Class<T> 作為參數,傳遞信息類型
  • TypeReference,傳遞類型信息
  • JavaType 作為參數

我們不能使用 JsonResponse<User>.class 傳遞給第一個 bullet point 中的方法,讓我們看看如何使用 TypeReferenceJavaType 進行泛型反序列化。

3.1. TypeReference

如我們所知,Java 在編譯時擦除泛型類型信息,但我們可以利用匿名內部類來在編譯期間保留類型信息。 Jackson 提供了抽象類 TypeReference,用於從派生子類獲取類型信息:

public abstract class TypeReference<T> {
    protected final Type _type;

    protected TypeReference() {
        Type superClass = this.getClass().getGenericSuperclass();
        this._type = ((ParameterizedType)superClass).getActualTypeArguments()[0];
    }
}

使用 TypeReference,我們可以按照以下方式創建匿名內部類用於泛型類型 JsonResponse<User>

TypeReference<JsonResponse<User>> typeRef = new TypeReference<JsonResponse<User>>() {};

這種保留泛型類型信息的做法被稱為超類型標記。 通過使用超類型標記,Jackson 將知道容器類型是 JsonResponse 及其類型參數是 User。

這是反序列化的完整測試用例:

@Test
void givenJsonObject_whenDeserializeIntoGenericTypeByTypeReference_thenCorrect() throws JsonProcessingException {
    String json = "{\"result\":{\"id\":1,\"firstName\":\"John\",\"lastName\":\"Lewis\"}}";

    TypeReference<JsonResponse<User>> typeRef = new TypeReference<JsonResponse<User>>() {};
    JsonResponse<User> jsonResponse = objectMapper.readValue(json, typeRef);
    User user = jsonResponse.getResult();

    assertThat(user.getId()).isEqualTo(1);
    assertThat(user.getFirstName()).isEqualTo("John");
    assertThat(user.getLastName()).isEqualTo("Lewis");
}

3.2. JavaType

如果類型參數 T 不是靜態的,則需要選擇 JavaType 而不是 TypeReference 來傳遞類型信息進行反序列化。 ObjectMapper 提供了此類方法,現在從 Jackson 2.5 開始推薦使用,並且我們可以使用 TypeFactory 來構造 JavaType 對象,其中包含我們的類型參數:

JavaType javaType = objectMapper.getTypeFactory().constructParametricType(JsonResponse.class, User.class);
JsonResponse<User> jsonResponse = objectMapper.readValue(json, javaType);

這裏 User.class 作為第二個參數傳遞給 constructParametricType 方法,可以輕鬆地更改為其他參數化類型。

4. 結論

在本文中,我們介紹了兩種將 JSON 字符串反序列化為具有泛型類型的對象的簡單方法。

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

發佈 評論

Some HTML is okay.