Gson, how to deserialize array or empty string

落花浮王杯 提交于 2019-12-17 16:48:17

问题


I trying to deserialize this json to array of objects:

[{
    "name": "item 1",
    "tags": ["tag1"]
},
{
    "name": "item 2",
    "tags": ["tag1","tag2"]
},
{
    "name": "item 3",
    "tags": []
},
{
    "name": "item 4",
    "tags": ""
}]

My java class looks like this:

public class MyObject
{
    @Expose
    private String name;

    @Expose
    private List<String> tags = new ArrayList<String>();
}

The problem is json's tags property which can be just empty string or array. Right now gson gives me error: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING

How should I deserialize this json?

I do not have any control to this json, it comes from 3rd pary api.


回答1:


I do not have any control to this json, it comes from 3rd pary api.

If you don't have the control over the data, your best solution is to create a custom deserializer in my opinion:

class MyObjectDeserializer implements JsonDeserializer<MyObject> {
    @Override
    public MyObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jObj = json.getAsJsonObject();
        JsonElement jElement = jObj.get("tags");
        List<String> tags = Collections.emptyList();
        if(jElement.isJsonArray()) {
            tags = context.deserialize(jElement.getAsJsonArray(), new TypeToken<List<String>>(){}.getType());
        }
        //assuming there is an appropriate constructor
        return new MyObject(jObj.getAsJsonPrimitive("name").getAsString(), tags);
    }
}

What it does it that it checks whether "tags" is a JsonArray or not. If it's the case, it deserializes it as usual, otherwise you don't touch it and just create your object with an empty list.

Once you've written that, you need to register it within the JSON parser:

Gson gson = new GsonBuilder().registerTypeAdapter(MyObject.class, new MyObjectDeserializer()).create();
//here json is a String that contains your input
List<MyObject> myObjects = gson.fromJson(json, new TypeToken<List<MyObject>>(){}.getType());

Running it, I get as output:

MyObject{name='item 1', tags=[tag1]}
MyObject{name='item 2', tags=[tag1, tag2]}
MyObject{name='item 3', tags=[]}
MyObject{name='item 4', tags=[]}



回答2:


Before converting the json into object replace the string "tags": "" with "tags": []




回答3:


Use GSON's fromJson() method to de serialize your JSON.

You can better understand this by the example given below:

import java.util.ArrayList;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

public class JsonToJava {

/**
 * @param args
 */
public static void main(String[] args) {
    String json = "[{\"firstName\":\"John\", \"lastName\":\"Doe\", \"id\":[\"10\",\"20\",\"30\"]},"
            + "{\"firstName\":\"Anna\", \"lastName\":\"Smith\", \"id\":[\"40\",\"50\",\"60\"]},"
            + "{\"firstName\":\"Peter\", \"lastName\":\"Jones\", \"id\":[\"70\",\"80\",\"90\"]},"
            + "{\"firstName\":\"Ankur\", \"lastName\":\"Mahajan\", \"id\":[\"100\",\"200\",\"300\"]},"
            + "{\"firstName\":\"Abhishek\", \"lastName\":\"Mahajan\", \"id\":[\"400\",\"500\",\"600\"]}]";

    jsonToJava(json);
}

private static void jsonToJava(String json) {
    Gson gson = new Gson();
    JsonParser parser = new JsonParser();
    JsonArray jArray = parser.parse(json).getAsJsonArray();

    ArrayList<POJO> lcs = new ArrayList<POJO>();

    for (JsonElement obj : jArray) {
        POJO cse = gson.fromJson(obj, POJO.class);
        lcs.add(cse);
    }
    for (POJO pojo : lcs) {
        System.out.println(pojo.getFirstName() + ", " + pojo.getLastName()
                + ", " + pojo.getId());
    }
}

}

POJO class:

public class POJO {

  private String        firstName;
  private String        lastName;
  private String[]  id;
  //Getters and Setters.

I hope this will solve your issue.




回答4:


You are mixing datatypes. You cant have both an Array and a string. Change

"tags": ""

to

"tags": null

and you are good to go.




回答5:


Use Jacskon Object Mapper

See below simple example

[http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/][1]




回答6:


Jackson type safety is way better than Gson. At times you will stackoverflow in Gson.



来源:https://stackoverflow.com/questions/31562157/gson-how-to-deserialize-array-or-empty-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!