GSON中的JSON数组解析,但对象为空
我试图用json将json字符串转换为对象。
我在下面有一个非常简单的例子,它运行,但结果答案是空的,即:我的答案对象的文本字段为空。
import com.google.gson.*; public class Meow { public static void main(String[] args) throws Exception{ Gson gson = new Gson(); String jsonOutput = "[{\"answer\":{\"text\":\"text1\"}},{\"answer\":{\"text\":\"text2\"}} ]"; Answer[] a = gson.fromJson(jsonOutput, Answer[].class); for(Answer i:a) { System.out.println(i.text); } } public class Answer { public String text; public Answer(String text) { super(); this.text=text; } public String toString(){ return text; } public void setText(String a){ this.text=a; } } }
因为您的JSON与您的class级不匹配。
您的JSON现在是一个对象数组,每个对象都包含一个answer
对象作为字段。
你的JSON就像你需要的样子:
String jsonOutput = "[{\"text\":\"text1\"},{\"text\":\"text2\"}]";
编辑以添加评论:
如果无法更改输出,则需要“包装器”。 就像是:
public class AnswerWrapper { public Answer answer; // etc }
并使用这些数组。 这就是JSON将映射到的内容。 它不能将它们视为Answer
对象,因为……它们不是。
再添加一个编辑:您的另一个选择是为您的类编写自定义反序列化器。 关于你是否应该这样做,我有点混乱,但它会起作用。 我说的原因是你有JSON 不是 Answer
对象的数组,但你想要它。 如果我在生产代码中遇到这个问题,我想我会很生气,因为不了解它发生的事情可能会令人困惑。
有了这个警告,你可以创建一个自定义的JsonDeserializer
并使用GsonBuilder
:
class AnswerDeserializer implements JsonDeserializer { public Answer deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException { return new Answer(je.getAsJsonObject().get("answer") .getAsJsonObject().get("text").getAsString()); } }
然后你的代码看起来像:
public static void main(String[] args) throws Exception{ String jsonOutput = "[{\"answer\":{\"text\":\"text1\"}},{\"answer\":{\"text\":\"text2\"}} ]"; GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Answer.class, new AnswerDeserializer()); Gson gson = gsonBuilder.create(); Answer[] a = gson.fromJson(jsonOutput, Answer[].class); for(Answer i:a) { System.out.println(i.text); } }
如果它是我,并且我有JSON不是我需要它但是想要使用GSON直接序列化/反序列化我将创建Answer
类作为隐藏细节的包装器:
/** * Due to how our JSON is being provided we created an inner * class. **/ public class Answer { private RealAnswer answer; private class RealAnswer { public String text; } ... }
使用公共getter / setter for Answer
访问私人RealAnswer
。 对于下一个人来说,这似乎更清晰,更容易理解。