【问题标题】:GSON creating an Array of ObjectsGSON 创建对象数组
【发布时间】:2014-11-07 02:38:23
【问题描述】:

我正在尝试创建格式的 patchRequest:

'[
{
    "op": "replace",
    "path": "/path1",
    "value": "val1"
},
{
    "op": "replace",
    "path": "/path2",
    "value": [
        {
            "name": "val2"
        }
    ]
}
]'

我尝试了很多愚蠢的事情,比如创建 2 个 json 对象并尝试将它们添加到 patchRequest 对象。或者尝试创建 2 个 patchRequestObj,然后将它们添加到 patchRequest 列表(因为我使用 patchRequest 作为我的输入,所以这会破坏目的)。 patchReq 对象到 JsonObjects,添加到 JSONArray 并转换回 patchRequest(失败)。

找不到任何对我的案例有帮助的文档。任何人都可以向我提出相同的建议。

谢谢。

【问题讨论】:

  • 可以使用 POJO 类型吗?只需创建一个 Patch[]List<Patch> 并对其进行序列化。
  • 这是一个包含两个地图的列表。其中一个地图包含一个元素,该元素是一个列表,其中包含一个只有一个元素的地图。

标签: java json gson patch


【解决方案1】:

在伪代码中:

mainArray = new JsonArray();
firstObject = new JsonObject();
firstObject.add("op", "replace");
firstObject.add("path", "/path1");
firstObject.add("value", "val1");
mainArray.add(firstObject);
secondObject = new JsonObject();
secondObject.add("op", "replace");
secondObject.add("path", "/path2");
innerArray = new JsonArray();
innerObject = new JsonObject();
innerObject.add("name", "val2");
innerArray.add(innerObject);
secondObject.add("value", innerArray);
mainArray.add(secondObject);
jsonString = mainArray.toJsonString();

【讨论】:

    【解决方案2】:

    我猜,逻辑是;

    1. 如果只有一个值,valuejson标签应该是一个原语 细绳。
    2. 如果有多个值,valuejson标签必须是一个 具有 name 字段的对象数组。

    对于这种情况,您可以编写自定义TypeAdapter

    public class ValueTypeAdapter extends TypeAdapter<Value> {
    
        @Override
        public Value read(JsonReader in) throws IOException {
            Value value = null;
    
            JsonParser jsonParser = new JsonParser();
            JsonElement je = jsonParser.parse(in);
    
            if(je instanceof JsonPrimitive) {   
                value = new Value();
                value.nameArr = new String[1];
                value.nameArr[0] = ((JsonPrimitive)je).getAsString();
            } else if (je instanceof JsonArray) {
                JsonArray jsonArr = (JsonArray)je;
                value = new Value();
                value.nameArr = new String[jsonArr.size()];
                for (int i = 0; i < jsonArr.size(); i++) {
                    JsonObject jo = (JsonObject)jsonArr.get(i); 
                    value.nameArr[i] = jo.get("name").getAsString();
                }
            }
    
            return value;
        }
    
        @Override
        public void write(JsonWriter out, Value value) throws IOException {
            if (value != null) {
                if (value.nameArr != null && value.nameArr.length > 0) {
                    if (value.nameArr.length == 1) {
                        out.value(value.nameArr[0]);
                    } else if (value.nameArr.length > 1) {
                        out.beginArray();
                        for (String nameVal : value.nameArr) {
                            out.beginObject();
                            out.name("name").value(nameVal);
                            out.endObject();
                        }
                        out.endArray();
                    }
                }
            }
        }       
    }
    

    你的 POJO:

    public class Item {
        private String op;
        private String path;
        private Value value;
    
        // TODO: Add Getters/Setters
    }
    
    public class Value {
        private String[] nameArr;
    
        // TODO: Add Getters/Setters
    }
    

    测试:

    注意:我使用了您的类似 json 字符串。不同之处在于第二个数组项包含 2 个值。在这个测试中,您将看到反序列化将完成,itemArr 将被正确填充。同样在将itemArr序列化为json字符串后,你会看到结果与传入的测试json字符串值相同。

        String json = "[{\"op\":\"replace\",\"path\":\"/path1\",\"value\":\"val1\"},{\"op\":\"replace\",\"path\":\"/path2\",\"value\":[{\"name\":\"val2\"},{\"name\":\"val3\"}]}]";
    
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Value.class, new ValueTypeAdapter());
        Gson gson = gsonBuilder.create();
    
        Item[] itemArr = gson.fromJson(json, Item[].class);
    
        String serialized = gson.toJson(itemArr);
    
        System.out.println("serialized:" + serialized);
        // NOTE: serialized output is same with incoming test value
    

    您可以从this site 阅读有关 TypeAdapters 的更多信息。

    【讨论】:

      猜你喜欢
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 2020-03-14
      • 2015-06-12
      相关资源
      最近更新 更多