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

时间:2015-06-09 19:55:39

标签: android json gson

我有一个json结构,我已粘贴在下面。我想使用Gson将json反序列化为java POJO,这非常简单,除了我想将其中一个字段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"
        }
    }
  }
}

我的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
}

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

2 个答案:

答案 0 :(得分:5)

您可以像这样创建自定义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;
    }

}

你这样使用它:

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

不好的部分不是你写的那么快,但至少你可以像这样自定义解析。

答案 1 :(得分:0)

使用此自定义类,添加所需内容:

 public class JsonParser 
{

    public static <T> List<T> parseList(String json_text, String json_path, Class<T> c)
    {
        Gson gson = new Gson();
        try
        {
            List<T> json_list = new ArrayList<>();
            List<Object> nodes = JsonPath.read(json_text, json_path);

            for(Object node : nodes)
            {
                json_list.add(gson.fromJson(node.toString(), c));
            }
            return (json_list);
        }
        catch(Exception e)
        {
            return (new ArrayList<>());
        }
    }
    public static <T> T parseObject(String json_text, Class<T> c)
    {
        return (new Gson()).fromJson(json_text, c);
    }

    public static <T> T getItemAtPosition (String json_text, String json_path)
    {
        try
        {
            return (JsonPath.read(json_text, json_path));
        }
        catch(Exception e)
        {
            return (null);
        }
    }
}

最终编辑:

因为你想要的只是你的JSON的一部分来保持JSONed字符串, 您可能只需要这一切(这意味着prime claim to fame):

String myData = JsonParser.getItemAtPosition(response,"$.data[*]").toString();