Sb Lon
Sb Lon

Reputation: 111

How to use @SerializedName alternate field in GSON to deserialize nested object?

In deserialization I am trying to map different JSON nodes to a single field using GSON.

I have the next field in a class:

private List<MyObjects> pages;

Incoming json may be:

{
  "pages": [
    {
      "pageNumber": "1"
    }
  ]
}

Or

{
  "pages": {
    "list": [
      {
        "pageNumber": "1"
      }
    ]
  }
}

I am trying to map the array of pages to the pages class field using this:

@SerializedName(value = "pages", alternate = "pages.list")
public List<MyObjects> pages;

but it doesnt work.

It seems that GSON does not support this. But maybe someone knows why?

Upvotes: 2

Views: 6518

Answers (1)

pirho
pirho

Reputation: 12215

For question

How to use alternate field in GSON?

the answer lies in the docs that I have partly copied here (and maybe you already know all or part of this).

For question

It seems GSON doesnt support this. But maybe someone know why?

Yes, maybe some Gson designer could answer to that. Personally I do not see any reason why it could not support JSONPath in that annotation attribute. Anyway I will concentrate to the question in the title.

This just is not how @SerializedName.alternate works now. If you take a look on the Gson API specs:

public abstract String[] alternate

Returns: the alternative names of the field when it is deserialized

(so names not paths)

Here is an example of how this annotation is meant to be used:

public class MyClass {
    @SerializedName("name") String a;
    @SerializedName(value="name1", alternate={"name2", "name3"}) String b;

and

While deserializing, all values specified in the annotation will be deserialized into the field. For example:

MyClass target = gson.fromJson("{'name1':'v1'}", MyClass.class);
assertEquals("v1", target.b);
target = gson.fromJson("{'name2':'v2'}", MyClass.class);
assertEquals("v2", target.b);
target = gson.fromJson("{'name3':'v3'}", MyClass.class);
assertEquals("v3", target.b);

In other words - when deserializing - it simply maps differently named fields to be deserialized to some one and the same field. It does not map field in alternate paths in Json source. It might be a nice feature, though.

So in the API doc example all fields that have name ["name1", "name2", "name3"] will be deserialized to MyClass field b. What it does not do - as I have understood - is to deserialize any nested Json object to that annotated field.

At the moment those two pages fields just seems like different objects to Gson.

Upvotes: 1

Related Questions