【问题标题】:GSON Custom Deserializer Handling NullGSON 自定义解串器处理 Null
【发布时间】:2016-03-30 13:03:35
【问题描述】:

我为android.net.Uri写了一个自定义的GSON类型适配器:

public class UriAdpter extends TypeAdapter<Uri> {

    @Override
    public void write(JsonWriter out, Uri value) throws IOException {
        out.value(value.toString());
    }

    @Override
    public Uri read(JsonReader in) throws IOException {
        return Uri.parse(in.nextString());
    }
}

它工作得很好,直到我解析的 JSON 提要给了我一个 null URI 值。然后它抛出了一个JsonSyntaxException

03-30 08:40:00.799 16340-16340/com.example.app D/NewsFragment: Failed to retrieve articles
        com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was NULL at line 1 column 23588 path $.data[5].thumbnail
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
            at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
            at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
            at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
            at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
            at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
            at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
            at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
            at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
            at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:144)
            at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:125)
            at rx.Observable$2.call(Observable.java:162)
            at rx.Observable$2.call(Observable.java:154)
            at rx.Observable$2.call(Observable.java:162)
            at rx.Observable$2.call(Observable.java:154)
            at rx.Observable.unsafeSubscribe(Observable.java:8314)
            at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)
        Caused by: java.lang.IllegalStateException: Expected a string but was NULL at line 1 column 23588 path $.data[5].thumbnail
            at com.google.gson.stream.JsonReader.nextString(JsonReader.java:830)
            at com.example.app.data.rest.adapter.UriAdapter.read(UriAdapter.java:26)
            at com.example.app.data.rest.adapter.UriAdapter.read(UriAdapter.java:16)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
            at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) 
            at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82) 
            at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61) 
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116) 
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216) 
            at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37) 
            at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25) 
            at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116) 
            at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211) 
            at retrofit2.OkHttpCall.execute(OkHttpCall.java:174) 
            at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:144) 
            at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:125) 
            at rx.Observable$2.call(Observable.java:162) 
            at rx.Observable$2.call(Observable.java:154) 
            at rx.Observable$2.call(Observable.java:162) 
            at rx.Observable$2.call(Observable.java:154) 
            at rx.Observable.unsafeSubscribe(Observable.java:8314) 
            at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94) 
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
            at java.lang.Thread.run(Thread.java:818) 

我尝试在解析之前检查in.nextString() 是否为null,但这不起作用,因为in.nextString() 引发了异常,而不是Uri.parse()。如何在使用 GSON 反序列化时检查 null 对象?

【问题讨论】:

    标签: android json gson json-deserialization


    【解决方案1】:

    你试过用JsonToken吗?

    public class UriAdpter extends TypeAdapter<Uri> {
    
        @Override
        public void write(JsonWriter out, Uri value) throws IOException {
            out.value(value.toString());
        }
    
        @Override
        public Uri read(JsonReader in) throws IOException {
            if (in.peek() == JsonToken.NULL) {
                in.nextNull();
                return null;
            }
            return Uri.parse(in.nextString());
        }
    }
    

    【讨论】:

    • 嗯,现在我得到一个不同的JsonSyntaxExceptionExpected a name but was null at line 1 column 23588 path $.data[5].thumbnail.
    • 啊,不,错过了in.nextNull()。已修复,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多