如何反序列化JSON对象,但将特定字段保留为String而不是嵌套对象?

how*_*ttl 10 android json gson

我有一个json结构,我粘贴在下面.我想将json反序列化为一个java POJO使用Gson它是非常简单的,除了我想保留其中一个字段data,作为String类型而不是嵌套对象.

JSON结构

{
  "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"
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我的POJO看起来像这样:

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
}
Run Code Online (Sandbox Code Playgroud)

data字段应保留为JSON格式的字符串.

我已经尝试实现自定义TypeAdapter并将字段作为字符串读取,但它失败了Expected a string but was BEGIN_OBJECT.

另请注意,我希望结构也能在序列化中进行维护 - 所以我可以将POJO序列化回原始的JSON结构.

编辑自定义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;
}
}
Run Code Online (Sandbox Code Playgroud)

Cat*_*ata 6

你可以创建一个像这样的自定义JsonDeserializer:

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

你这样使用它:

GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Sample.class, new SampleGSONParserAdapter());
Gson gson = gsonBuilder.create();
Run Code Online (Sandbox Code Playgroud)

坏的部分是没有你写的那么快,但至少你可以做这样的自定义解析.