4

Let say there is a JSON like this

{
  "data" : {
    "messages" : {
      "count" : 2,
      "data" : [
        "message 1",
        "message 2"
      ]
    },
    "user" : {
      "f_name" : "Mark",
      "l_name" : "lewis"
    },
    "city" : "London",
    "address" : "221b Baker Street, London"
  }
}

Can I achieve something like this with GSON?

public class JSData {
    public String city;
    public String address;
    public Array messages;
    @SerializedName("user.f_name")
    public String firstName;
    @SerializedName("user.l_name")
    public String lastName;
}

I want to access user.f_name directly, so I don't have to create wrapper for user and can directly convert it using

 JSData topic = gson.fromJson(jsonObj, JSData.class);
Tek Yin
  • 3,011
  • 3
  • 25
  • 42

2 Answers2

0

I think you should create a class User like this

    public class User {
        @SerializedName("f_name")
        public String firstName;

        @SerializedName("l_name")
        public String lastName;
    }

    public class JSData {
        public String city;
        public String address;
        public Array messages;

        @SerializedName("user")
        public User user;
    }
Phien
  • 148
  • 1
  • 14
  • I know to how to use this, but I wonder if I can take f_name and l_name and put it into JSData without creating `User` wrapper. – Tek Yin Apr 24 '15 at 05:02
  • I think we have a complex solution by using JsonDeserializer. – Phien Apr 24 '15 at 05:20
-1

I don't know how to archive @SerializedName("user.f_name") like way,
but flatten inner field is archivable thanks to JsonDeserializer.

Assume that we have

 {   
   "publishDate": {
     __type: "Date",
     iso: "2014-11-05T02:27:00.000Z"
    },
 ...
 }

and we want to convert inner "iso" field to upper "publishDate" as Date.

So, JsData class looks like this.

public class JsData {
  // publishDate is JSONObject. but get it as Date!
  public Date publishDate;
  ...
}

Implements JsonDeserializer<Date> and register to gson to archive custom deserialization. When gson detect Date field, this implementation will be called.

public static class PublishDateDeserializer implements JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {
      // this deserializer is only for "publishDate"
      // real json is jsonobject. get inner "iso"
      String iso = json.getAsJsonObject().get("iso").getAsString();
      DateFormat parser = new SimpleDateFormat(DATE_JSON_PATTERN);
      try {
        return parser.parse(iso);
      } catch (ParseException e) {
        throw new JsonParseException(e);
      }
    }
  }

Then register via builder

Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new PublishDateDeserializer()).create();
gson.fromJson(json, JsData.class);

I hope it will help.

ytRino
  • 1,450
  • 15
  • 28
  • I think this answer seems to be off the point. He want to put inner array to JSData without any other wrapper class. – JK Park Apr 24 '15 at 06:16
  • yes, i know this is not perfect solution. but inner field (`f_name` for him, `iso` for me) is converted to upper level. whats "wrapper class" means? – ytRino Apr 24 '15 at 08:33