簡體   English   中英

從JSON確定Object的類型並使用GSON創建對象

[英]Determining type of Object from JSON and create object using GSON

我在我的應用程序中使用Gson,我有幾個Java對象,我通過使用GSON將它轉換為JSON來呈現給前端。 我知道如何使用gson將JSON轉換回Java對象。

我有這個用例:當我向GSON提供一個特定的JSON字符串時,我希望它找到從中獲取JSON字符串的對象的類型,並給我一個該類型的對象。

使用GSON,只有在傳遞fromJson方法中的Object類時, fromJson返回對象。 但是,無論如何我可以讓gson自己決定嗎? 我無法控制另一方生成的對象。

例:

Person person = new Person();
SomeRandomObject obj = new SomeRandomObject();

String personJson = gson.toJson(person);
String anotherJson = gson.toJson(obj);

現在如果我想將它轉換回對象,我使用這個:

Person p = gson.fromJson(personJson,Person.class);

但無論如何,我可以得到這樣的對象:

Object object = gson.fromJson(anotherJson,*TheCorrespondingObject.class*)

我知道我可以通過嘗試使用GSON拋出異常的不同對象的JSON字符串來實現這一點,但我不認為這是正確的方法。

最好,最簡單的方法是將JSON本身包裝在包含該類型的容器中。

例如:

{
  "foo":"bar"
}

{
  "type":"FooContainer"
  "value": {
     "foo":"bar"
  }
}

但是,你說你不能這樣做,所以我不會詳細介紹如何實際進行反序列化。 如果你可以做這個有限的改變,你可以編寫一個TypeAdapterFactory並讓Gson完成所有其余的工作,通過在create()方法中使用傳遞的Gson對象並在read方法中調用gson.fromJson() ,這將比下面的方法少得多的代碼。


想想這里真正需要發生什么。 不知何故,您需要檢測Websphere MQ對象中的數據並使用它來計算出來。 以這種方式檢測它將采用代碼,分析您收到的數據,並吐出正確的對象。

你要面對的第一個問題是,你不想這樣做:

Object myObj = gson.fromJson(jsonString, Object.class);

這意味着您將覆蓋默認的基本反序列化程序,它可能具有各種令人討厭的副作用。 對於某種自定義對象,最好將行為包裝在TypeAdapter中:

public class Wrapper {
  public Object data; // Encapsulate this if you want, this is just for brevity
}

我會把鑄造/仿制品留給你。 有很多方法可以做到,但我建議將訪問者模式作為一個不錯的選擇,或者創建枚舉類型對象 如果你可以讓所有收到的對象類型實現某種界面以使這更容易,那將是最好的,但同樣,這不是你的主要問題。

您的主要問題實際上是在代碼中檢測這些類。 現在我們有了一個包裝類,我們可以使用它:

Wrapper myWrapper = gson.fromJson(jsonString, Wrapper.class);

現在,每個生成的類都是同一個類,所以Gson很高興。 但是我們在哪里制定規則? 它們會進入您的自定義TypeAdapter

public class WrapperTypeAdapter extends TypeAdapter<Wrapper> {
    @Override
    public final void write(JsonWriter out, Wrapper value) throws IOException {
        if(value == null) {
            out.nullValue();
            return;
        }

        // Don't worry about Write for now, obviously
    }

    @Override
    public final Wrapper read(JsonReader in) throws IOException {
        if(in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }

        Wrapper wrapper = new Wrapper();

        // HERE IS WHERE YOU GET TO WRITE CODE

        return wrapper;
    }
}

在read方法中,當您流式標記時,您可以使用基於您希望JSON標記本身的規則來確定它將成為什么類,然后構造新對象。 我建議將其分解為許多方法,如MyFoo readMyFoo(JsonReader)MyBar readMyBar(JsonReader)等。我很難在不了解JSON本身的情況下深入了解更多細節,但這應該足以讓你開始。

通用答案:您必須向生成的JSON添加一些內容以指示它的生成內容。

說,而不是

{
    "name": "John"
}

你會生成類似的東西:

{
    "type": "Customer"
    "name": "John"
}

如何在GSON中做到這一點留給讀者練習。 ;)


編輯:哦,你不能篡改JSON。 沒關系。

盡管如此,如果沒有某種標識符,很難以通用方式執行此操作,特別是考慮到某些類可能恰好具有完全相同的字段。

通過分析原始字符串手動:

if (jsonString.indexOf(..) > 0) {
   //reading Person
} else {
   //reading SomeRandomObject
}

或者您可以使用JSON Simple並讀取任何JSON

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM