知識庫 / JSON RSS 訂閱

Gson反序列化菜譜

JSON
HongKong
9
10:04 PM · Dec 05 ,2025

在本食譜中,我們將探索各種將 JSON 映射為 Java 對象 的方法,使用流行的 Gson 庫

1. 將 JSON 反序列化為單個基本對象

讓我們從簡單的開始——我們將將一個簡單的 JSON 反序列化為 Java 對象,即 Foo

public class Foo {
    public int intValue;
    public String stringValue;

    // + standard equals and hashCode implementations
}

解決方案如下:

@Test
public void whenDeserializingToSimpleObject_thenCorrect() {
    String json = "{"intValue":1,"stringValue":"one"}";

    Foo targetObject = new Gson().fromJson(json, Foo.class);

    assertEquals(targetObject.intValue, 1);
    assertEquals(targetObject.stringValue, "one");
}

2. 將 JSON 反序列化為通用對象

接下來,讓我們使用泛型定義一個對象:

public class GenericFoo<T> {
    public T theValue;
}

將 JSON 解碼為這種類型的對象:

@Test
public void whenDeserializingToGenericObject_thenCorrect() {
    Type typeToken = new TypeToken<GenericFoo<Integer>>() { }.getType();
    String json = "{"theValue":1}";

    GenericFoo<Integer> targetObject = new Gson().fromJson(json, typeToken);

    assertEquals(targetObject.theValue, new Integer(1));
}

3. 使用包含額外未知字段的 JSON 對象進行反序列化

接下來,讓我們反序列化一些複雜的 JSON,其中包含額外的 未知字段

@Test
public void givenJsonHasExtraValues_whenDeserializing_thenCorrect() {
    String json = 
      "{"intValue":1,"stringValue":"one","extraString":"two","extraFloat":2.2}";
    Foo targetObject = new Gson().fromJson(json, Foo.class);

    assertEquals(targetObject.intValue, 1);
    assertEquals(targetObject.stringValue, "one");
}

如你所見,Gson 會忽略未知的字段,並僅匹配它能夠匹配的字段。

4. 使用非匹配字段名稱反序列化 JSON 到對象

現在,讓我們看看 Gson 如何處理包含字段與我們的 Foo 對象字段不匹配的 JSON 字符串:

@Test
public void givenJsonHasNonMatchingFields_whenDeserializingWithCustomDeserializer_thenCorrect() {
    String json = "{"valueInt":7,"valueString":"seven"}";

    GsonBuilder gsonBldr = new GsonBuilder();
    gsonBldr.registerTypeAdapter(Foo.class, new FooDeserializerFromJsonWithDifferentFields());
    Foo targetObject = gsonBldr.create().fromJson(json, Foo.class);

    assertEquals(targetObject.intValue, 7);
    assertEquals(targetObject.stringValue, "seven");
}

請注意,我們已註冊了一個 自定義反序列化器——它能夠正確地從 JSON 字符串中解析出字段並將其映射到我們的 Foo

public class FooDeserializerFromJsonWithDifferentFields implements JsonDeserializer<Foo> {

    @Override
    public Foo deserialize
      (JsonElement jElement, Type typeOfT, JsonDeserializationContext context) 
      throws JsonParseException {
        JsonObject jObject = jElement.getAsJsonObject();
        int intValue = jObject.get("valueInt").getAsInt();
        String stringValue = jObject.get("valueString").getAsString();
        return new Foo(intValue, stringValue);
    }
}

5. 將 JSON 數組反序列化為 Java 對象數組

接下來,我們將反序列化 一個 JSON 數組,將其轉換為 Foo 對象類型的 Java 數組:

@Test
public void givenJsonArrayOfFoos_whenDeserializingToArray_thenCorrect() {
    String json = "[{"intValue":1,"stringValue":"one"}," +
      "{"intValue":2,"stringValue":"two"}]";
    Foo[] targetArray = new GsonBuilder().create().fromJson(json, Foo[].class);

    assertThat(Lists.newArrayList(targetArray), hasItem(new Foo(1, "one")));
    assertThat(Lists.newArrayList(targetArray), hasItem(new Foo(2, "two")));
    assertThat(Lists.newArrayList(targetArray), not(hasItem(new Foo(1, "two"))));
}

6. 將 JSON 數組反序列化為 Java 集合

接下來,將 JSON 數組直接反序列化為 Java 集合:

@Test
public void givenJsonArrayOfFoos_whenDeserializingCollection_thenCorrect() {
    String json = 
      "[{"intValue":1,"stringValue":"one"},{"intValue":2,"stringValue":"two"}]";
    Type targetClassType = new TypeToken<ArrayList<Foo>>() { }.getType();

    Collection<Foo> targetCollection = new Gson().fromJson(json, targetClassType);
    assertThat(targetCollection, instanceOf(ArrayList.class));
}

7. 將 JSON 解析為嵌套對象

接下來,讓我們定義我們的嵌套對象——FooWithInner

public class FooWithInner {
    public int intValue;
    public String stringValue;
    public InnerFoo innerFoo;

    public class InnerFoo {
        public String name;
    }
}

以下是如何反序列化包含此嵌套對象的輸入:

@Test
public void whenDeserializingToNestedObjects_thenCorrect() {
    String json = "{\"intValue\":1,\"stringValue\":\"one\",\"innerFoo\":{\"name\":\"inner\"}}";

    FooWithInner targetObject = new Gson().fromJson(json, FooWithInner.class);

    assertEquals(targetObject.intValue, 1);
    assertEquals(targetObject.stringValue, "one");
    assertEquals(targetObject.innerFoo.name, "inner");
}

8. 使用自定義構造函數反序列化 JSON

最後,讓我們看看如何強制在反序列化過程中使用特定的構造函數,而不是默認的無參數構造函數,使用 <em >InstanceCreator</em>

public class FooInstanceCreator implements InstanceCreator<Foo> {

    @Override
    public Foo createInstance(Type type) {
        return new Foo("sample");
    }
}

以下是如何在反序列化中使用我們的 FooInstanceCreator 的方法:

@Test
public void whenDeserializingUsingInstanceCreator_thenCorrect() {
    String json = "{\"intValue\":1}";

    GsonBuilder gsonBldr = new GsonBuilder();
    gsonBldr.registerTypeAdapter(Foo.class, new FooInstanceCreator());
    Foo targetObject = gsonBldr.create().fromJson(json, Foo.class);

    assertEquals(targetObject.intValue, 1);
    assertEquals(targetObject.stringValue, "sample");
}

請注意,而不是 null,Foo.stringValue 等於 sample,因為我們使用了以下構造函數:

public Foo(String stringValue) {
    this.stringValue = stringValue;
}

9. 結論

本文介紹瞭如何利用 Gson 庫來解析 JSON 輸入,涵蓋了單對象和多對象場景下的常見用例。

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

發佈 評論

Some HTML is okay.