前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >处理Retrofit MalformedJsonException报错

处理Retrofit MalformedJsonException报错

作者头像
技术小黑屋
发布2020-01-23 21:33:32
1.2K0
发布2020-01-23 21:33:32
举报
文章被收录于专栏:技术小黑屋技术小黑屋

使用Retrofit配合GsonConverter,我们能很好地将网络响应内容转换成对应的对象。比如像下面这样。

Retrofit网络接口方法

1 2 3 4 5 6 7

public interface DroidNetwork { @GET("/content/test.json") Call<DroidResponse> jsonData(); @GET("/content/helloworld.txt") Call<String> plainText(); }

对应的应用方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

val retrofit = Retrofit.Builder() .baseUrl("https://asset.droidyue.com/") .addConverterFactory(GsonConverterFactory.create()) .build() val droidNetwork = retrofit.create(DroidNetwork::class.java) droidNetwork.jsonData().enqueue(object : Callback<DroidResponse> { override fun onFailure(call: Call<DroidResponse>?, t: Throwable?) { t?.printStackTrace() } override fun onResponse(call: Call<DroidResponse>?, response: Response<DroidResponse>?) { dumpMessage("onResponse content=${response?.body()}") } })

上面的方法执行都很正常,可是执行这个方法的时候就会报错。

1 2 3 4 5 6 7 8 9 10

droidNetwork.plainText().enqueue(object : Callback<String> { override fun onFailure(call: Call<String>?, t: Throwable?) { Exception("causedByPlainText", t)?.printStackTrace() } override fun onResponse(call: Call<String>?, response: Response<String>?) { dumpMessage("onResponse content=${response}") } })

崩溃的信息如下

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

W System.err: java.lang.Exception: causedByPlainText W System.err: at com.example.secoo.retrofitconvertor.MainActivity$doNetworkRequest$2.onFailure(MainActivity.kt:41) W System.err: at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$2.run(ExecutorCallAdapterFactory.java:80) W System.err: at android.os.Handler.handleCallback(Handler.java:891) W System.err: at android.os.Handler.dispatchMessage(Handler.java:102) W System.err: at android.os.Looper.loop(Looper.java:207) W System.err: at android.app.ActivityThread.main(ActivityThread.java:7470) W System.err: at java.lang.reflect.Method.invoke(Native Method) W System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958) W System.err: Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $ W System.err: at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1568) W System.err: at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1409) W System.err: at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:593) W System.err: at com.google.gson.stream.JsonReader.peek(JsonReader.java:425) W System.err: at com.google.gson.internal.bind.TypeAdapters$16.read(TypeAdapters.java:393) W System.err: at com.google.gson.internal.bind.TypeAdapters$16.read(TypeAdapters.java:390) W System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39) W System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27) W System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:223) W System.err: at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121) W System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206) W System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) W System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) W System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) W System.err: at java.lang.Thread.run(Thread.java:784)

原因其实很简单

解决方法有两个

这里我们介绍后者的处理方法,这里我们使用ResponseBody而不是之前的String,然后按照如下代码应用即可。

接口代码

1 2

@GET("/content/helloworld.txt") Call<ResponseBody> plainTextAsResponseBody();

应用代码

1 2 3 4 5 6 7 8 9 10

droidNetwork.plainTextAsResponseBody().enqueue(object : Callback<ResponseBody> { override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) { t?.printStackTrace() } override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) { dumpMessage("onResponse of plainTextAsResponseBody content=${response?.body()?.string()}") } })

附加内容

如果在某种情况下,我们只关心请求操作,而不关心响应内容,我们可以这样使用

1 2

@GET("/content/helloworld.txt") Call<Void> ignoreResult();

上面的代码相对更加高效,因为这里省略了将响应内容转成内存对象的过程。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 附加内容
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com