GSON解析未指定的类型变量
我用GSON库解析服务器JSON响应。 后端人员有时会告诉我:“我们不能出于某种原因在JSON中指定变量类型”(旧的PHP,他们不知道如何去做等等)。 GSON喜欢在其对象模型中进行强类型输入。 所以我不能将Object解析为String。
GSON等待:
{ "service":{ "description":null, "name":"Base", "id":"4c7a90410529" } }
但它得到(空数据):
"service": ""
我明白了
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1396
解析此类响应的最佳做法是什么?
另一个问题:我如何构建对象,它可以识别不时返回为Integer或String的Integer变量? 相同的服务器端问题。
"data": "1"
要么
"data": 1
我知道 – 我们应该在Java中使用特定类型。 但有时候做出让步是值得的,
谢谢
编辑:我的解决方案基于Java Developer的答案。
ServiceDeserializer类根据其内部值反序列化每个对象。
public class ServiceDeserializer implements JsonDeserializer{ @Override public ServiceState deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String name = ""; String uuid = ""; String description = ""; if (json.isJsonObject()) { JsonObject obj = json.getAsJsonObject(); if (!obj.get("name").isJsonNull()) { name = obj.get("name").getAsString(); } if (!obj.get("uuid").isJsonNull()) { uuid = obj.get("uuid").getAsString(); } if (!obj.get("description").isJsonNull()) { description = obj.get("description").getAsString(); } } return new ServiceState(name, uuid, description); } }
我的GSON构造函数与ServiceState的类型适配器。
Gson gson = new GsonBuilder() .registerTypeAdapter(ServiceState.class, new ServiceDeserializer()) .create();
如果你想坚持使用gson
你可以提供一个自定义的反序列化器 。 由于我们知道service
是基本json
字符串的属性或嵌入在其他property
,因此我们可以使用反序列化器逐步解析有问题的组件并相应地处理它们。
public class MyJsonDeserializer implements JsonDeserializer { @Override public YourParsedData deserialize(final JsonElement je, final Type type, final JsonDeserialization Context jdc) throws JsonParseException { final JsonObject obj = je.getAsJsonObject(); //our original full json string final JsonElement serviceElement = obj.get("service"); //here we provide the functionality to handle the naughty element. It seems emtpy string is returned as a JsonPrimitive... so one option if(serviceElement instanceOf JsonPrimitive) { //it was empty do something } return YourParsedData.create(); //provide the functionality to take in the parsed data } }
自定义反序列化器将按如下方式调用:
final Gson gson = new GsonBuilder().registerTypeAdapter(YourParsedData.class, new MyJsonDeserializer()).create(); gson.fromJson("{service: ''}", YourParsedData.class);
我输入了所有这些,如果我错过了一些语法我的道歉。
在尝试将其反序列化为Response
Java对象之前,需要抓取JSON响应。 您可以使用Java org.json解析器来validationservice
对象是否确实存在并以其他方式修复它。
String json = "{\"service\":{\r\n" + " \"description\":null,\r\n" + " \"name\":\"Base\",\r\n" + " \"id\":\"4c7a90410529\"\r\n" + "}}"; String json2 = "{\"service\":\"\"}"; JSONObject root = new JSONObject(json); // JSONObject root = new JSONObject(json2); if (root.optJSONObject("service") == null) { root.put("service", new JSONObject()); } Gson gson = new Gson(); Response response = gson.fromJson(root.toString(), Response.class); System.out.println(response.getService());
输出 :
// for JSONObject root = new JSONObject(json); Service [id=4c7a90410529, name=Base, description=null] // for JSONObject root = new JSONObject(json2); Service [id=null, name=null, description=null]
其次, Gson
足够聪明,可以进行简单的转换,比如String
to Integer
等。因此,反序列化这样的JSON属性不应该给你带来任何麻烦。
System.out.println(gson.fromJson("10", Integer.class)); // 10 System.out.println(gson.fromJson("\"20\"", Integer.class)); // 20
您的json无效,任何Json解析器都无法解析语法错误的json:
"service": { "description": null, "name": "Base", "id": "4c7a90410529" }
应该用大括号括起来,如下所述:
{ "service": { "description": null, "name": "Base", "id": "4c7a90410529" } }
json结构包含在{}
。 您的回答似乎缺失了。 您可以手动将{
和}
附加到字符串的开头和结尾,以使其成为有效的json结构。
完成此操作后,您可以使用Gson正常解析您的json响应。
解析此类响应的最佳做法是什么?
使用足够好的Json解析器。 这绰绰有余。 并尝试使用一个表示与响应完全相同的结构的类,以避免手动逐级解析json响应。
- 在VideoView中播放来自url的video
- 找不到类’twitter4j.http.AccessToken’
- 在XML或java文件中编写相同的代码(用于布局)之间是否存在性能差异?
- Android – 如何按日期对arrayList进行排序?
- Android,添加没有XML布局的新视图
- InputStreamReader并从.txt文件中读取随机行
- 在Room中创建Generic DAO接口时,“参数的类型必须是使用@Entity注释的类”
- 使用ACTION_IMAGE_CAPTURE时返回什么数据?
- 如何将“2017-04-26T20:55:00.000Z”字符串转换为java android studio中的日期