Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I deserialize a JSON object but keep a specific field as a String instead of a nested object?

Tags:

json

android

gson

I have a json structure which I've pasted below. I'd like to deserialize the json into a java POJO using Gson which is pretty straight-forward, except that I want to keep one of the fields, data, as a String type instead of a nested object.

JSON structure

{
  "created_on": "2015-06-04T16:12:04-0700",
  "modified_on": "2015-06-04T16:12:09-0700",
  "identifier": "sample",
  "name": "some name",
  "summary": "some summary",
  "data": {
    "$type": "a_type",
    "some_other_stuff": {
        "more_stuff": "lorem ipsum"
    },
    "type2": {
        "$type": "another_type",
        "other_stuff": {
            "event_more_stuff": "lorem ipsum"
        }
    }
  }
}

My POJO would then look like this:

public class Sample {
  private String identifier; // "sample"
  private String created_on; // "2015-06-04T16:12:04-0700"
  private String modified_on; // "2015-06-04T16:12:09-0700"
  private String name; // "some name"
  private String summary; // "some summary"
  private String data; // "{ \"$type\": ... }"

  // getters and setters
}

The data field should remain as a JSON-formatted String.

I've tried implementing a custom TypeAdapter and reading the field as a String, but it fails with Expected a string but was BEGIN_OBJECT.

Also please note, I would like the structure to be maintained on serialization as well - so I can serialize the POJO back to the original JSON structure.

Edit Custom TypeAdapter:

public class SampleTypeAdapter extends TypeAdapter<Sample> {
@Override
public void write(JsonWriter out, Sample sample) throws IOException {
    out.beginObject();

    out.name("identifier").value(sample.getIdentifier());
    out.name("name").value(sample.getName());
    out.name("data").value(sample.getData());
    out.name("summary").value(sample.getSummary());
    out.name("modified_on").value(sample.getModifiedOn());
    out.name("created_on").value(sample.getCreatedOn());

    out.endObject();
}

@Override
public Sample read(JsonReader in) throws IOException {
    final Sample sample = new Sample();

    in.beginObject();
    while (in.hasNext()) {
        String nextName = in.nextName();
        switch (nextName) {
            case "identifier":
                sample.setIdentifier(in.nextString());
                break;
            case "name":
                sample.setName(in.nextString());
                break;
            case "data":
                sample.setData(in.nextString()); // <-- fails here
                break;
            case "summary":
                sample.setSummary(in.nextString());
                break;
            case "modified_on":
                sample.setModifiedOn(in.nextString());
                break;
            case "created_on":
                sample.setCreatedOn(in.nextString());
                break;
            default:
                in.skipValue();
                break;
        }
    }
    in.endObject();

    return sample;
}
}
like image 533
howettl Avatar asked Jun 09 '15 19:06

howettl


People also ask

Which method is used to deserialize a JSON string into JS object?

To Deserialize a JSON into a JavaScript object, here we will use a common method JSON. parse() method. JavaScript Object Notation is used to exchange data to or from a web server or RESTFull API. The data received from a web server is always a string.

How do I deserialize an object in JSON?

A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.

What is the difference between serialize and deserialize JSON?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object). If you serialize this result it will generate a text with the structure and the record returned.


1 Answers

You could create a custom JsonDeserializer like this one:

public class SampleGSONParserAdapter implements
        JsonDeserializer<Sample> {

    @Override
    public Sample deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        Sample sample = new Sample();
        JsonObject sampleJsonObject = json.getAsJsonObject();

        sample.setName(sampleJsonObject.get("name").getAsString());

        // do the other parsing stuff here..

        // getting the data object as a string
        sample.setJsonString(sampleJsonObject.get("data").toString());

        return sample;
    }

}

And you use it like this:

GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Sample.class, new SampleGSONParserAdapter());
Gson gson = gsonBuilder.create();

The bad part is that is not as fast as the one you wrote but at least you can do custom parsing like this one.

like image 92
Cata Avatar answered Sep 22 '22 04:09

Cata