我有一些JSON数据,如果某些字段从未有过值,则这些字段可以为null。
我决定创建自己的反序列化器来展平一些嵌套的JSON数据。
然而,我注意到当我的deserialiser遇到一个JSON Null时,它抛出以下内容
java.lang.UnsupportedOperationException: JsonNull
这在我使用默认的GSON反序列化器之前从未发生过
public class ShopDeserializer implements JsonDeserializer<Shop> {
@Override
public Shop deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject root = json.getAsJsonObject();
String shopName = root.get("name").getAsString();
String description = root.get("description").getAsString();
String openingTime = root.get("opening_time").getAsString();
String contactEmail = root.get("contact_email").getAsString();
String telNumber = root.get("tel_number").getAsString();
String website = root.get("website").getAsString();
基本上JSON中的一个字段值可以为null,但是我真的需要对每个字段进行空值检查吗?
默认值如何忽略它
再说一遍:我真的需要对每个字段进行空检查吗?
MCVE
此链接是一个非常小的Android程序,可以复制问题
https://www.dropbox.com/sh/b8uy179jo4yz2o7/AACbiWgLf0ZClZJpYS7KFFEBa?dl=0
这里是代码的主要部分,带有解释
String JsonBad = "{\"shops\":{\"url\":\"www.exmaple/20932\",\"name\":\"Some shop 1\",\"description\":\"really nice\",\"opening_time\":\"every day from 9am to 6pm\",\"entry_fee\":null}}";
String JsonGood = "{\"shops\":{\"url\":\"www.exmaple/2092\",\"name\":\"Some shop 2\",\"description\":\"quite expensive\",\"opening_time\":\"every day from 9am to 6pm\",\"entry_fee\":\"£10\"}}";
Gson gson = new GsonBuilder().registerTypeAdapter(Shop.class, new ShopDeserializer()).create();
Shop good = gson.fromJson(JsonGood, Shop.class);
Shop bad = gson.fromJson(JsonBad, Shop.class);
有两个JSON字符串。 JSON bad有一个名为entry_fee的字段,该字段为null但JSON good的值为£10(非null)
private static class ShopDeserializer implements JsonDeserializer<Shop> {
@Override
public Shop deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject root = json.getAsJsonObject().get("shops").getAsJsonObject();
String urlToShowCall = root.get("url").getAsString();
String shopName = root.get("name").getAsString();
String description = root.get("description").getAsString();
String openingTime = root.get("opening_time").getAsString();
String entryFee = root.get("entry_fee").getAsString();
return new Shop(urlToShowCall, shopName, description, openingTime, entryFee);
}
}
上面是我的JsonDeserializer。当它到达JSON时它会抛出以下内容
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: FATAL EXCEPTION: main
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: Process: com.test.gsonissue, PID: 5412
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.gsonissue/com.test.gsonissue.MainActivity}: java.lang.UnsupportedOperationException: JsonNull
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.-wrap11(ActivityThread.java)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: Caused by: java.lang.UnsupportedOperationException: JsonNull
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.google.gson.JsonElement.getAsString(JsonElement.java:191)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.test.gsonissue.MainActivity$ShopDeserializer.deserialize(MainActivity.java:57)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.test.gsonissue.MainActivity$ShopDeserializer.deserialize(MainActivity.java:48)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.google.gson.Gson.fromJson(Gson.java:814)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.google.gson.Gson.fromJson(Gson.java:779)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.google.gson.Gson.fromJson(Gson.java:728)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.google.gson.Gson.fromJson(Gson.java:700)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.test.gsonissue.MainActivity.onCreate(MainActivity.java:44)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6237)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.-wrap11(ActivityThread.java)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-03 16:33:20.049 5412-5412/? E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
但是,只做JSON好工作。