Gson,如何反序列化数组或空字符串

时间:2015-07-22 11:44:48

标签: java android json gson

我试图将这个json反序列化为对象数组:

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

我的java类看起来像这样:

public class MyObject
{
    @Expose
    private String name;

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

问题是json的标签属性,它可以只是空字符串或数组。现在gson给了我错误:com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING

我应该如何反序化这个json?

我对这个json没有任何控制权,它来自第三个pary api。

6 个答案:

答案 0 :(得分:7)

  

我对这个json没有任何控制权,它来自第三个pary api。

如果您无法控制数据,那么我认为最佳解决方案是创建自定义反序列化器:

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

它检查"tags"是否为JsonArray是做什么的。如果是这样的话,它会像往常一样对其进行反序列化,否则您不会触摸它,只需使用空列表创建对象。

一旦你写完了,就需要在JSON解析器中注册它:

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

运行它,我得到输出:

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

答案 1 :(得分:1)

在将json转换为object之前,将"tags": ""替换为"tags": []

答案 2 :(得分:0)

您正在混合数据类型。你不能同时拥有一个数组和一个字符串。改变

"tags": ""

"tags": null

你很高兴。

答案 3 :(得分:0)

使用GSON的fromJson()方法对您的JSON进行反序列化。

您可以通过以下示例更好地理解这一点:

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课程:

public class POJO {

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

我希望这能解决你的问题。

答案 4 :(得分:-1)

使用Jacskon Object Mapper

见下面的简单例子

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

答案 5 :(得分:-3)

Jackson类型的安全性比Gson好。有时你会在Gson中进行stackoverflow。