简体   繁体   中英

GSON creating an Array of Objects

I am trying to create a patchRequest of the format :

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

I have tried a lot of stupid things, like creating 2 json objects and Trying to add them to patchRequest object. OR trying to create 2 patchRequestObj, then add them to patchRequest List (that defeats purpose since i am using patchRequest as my input). patchReq objects to JsonObjects, add to JSONArray and convert back to patchRequest (this fails).

Could not find any documentation that is helpful for my case. Can anyone suggest the same to me.

Thanks.

In pseudocode:

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();

As I guess, logic is;

  1. If there is only one value, value json tag should be a primitive string.
  2. If there are more than one values, value json tag must be an array of objects that has name fields.

在此处输入图片说明

For this case you can write a custom 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();
                }
            }
        }
    }       
}

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

Test:

Note: I've used similar json string of yours. Difference is second array item holds 2 values. In this test you'll see that deserialization will be done and itemArr will be filled correctly. Also after serialization of itemArr to json string, you'll see that the result is same with incoming test json string value.

    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

You can read more about TypeAdapters from this site .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM