问题背景 针对一个接口,server给出的是一个JSON, 端上想要用string去接收
我们测试可以用https://jsonplaceholder.typicode.com/posts/3 来测试
1 2 3 4 5 6 { "userId" : 1 , "id" : 3 , "title" : "title" , "body" : "body" }
我们是不是能用直接用String来接收?
1 2 3 4 interface ApiService { @GET("/posts/33" ) fun getPage () : Single<String> }
问题分析 这里我们可以会想都是字符串,肯定是可以的,但是转念一下,JSON和JSON字符串是不一样的, 这个是JSON
1 2 3 4 5 6 { "userId" : 1 , "id" : 3 , "title" : "title" , "body" : "body" }
这是JSON字符串 “{"userId":1,"id":3,"title":"title","body":"body"}” 我们直接来测试, 会得到这样的错误❎, 大意是期望的是一个String,但是得到是一个JSON类型 Expected a string but was BEGIN_OBJECT at line 1 column 2 path $ 当我们调用一个interface的api的时候,通过注解登拿到这个方法的返回类型,然后去找Response Body Converter
1 2 3 4 5 6 7 8 9 10 <init >:33 , GsonResponseBodyConverter (retrofit2.converter.gson) responseBodyConverter:65 , GsonConverterFactory (retrofit2.converter.gson) nextResponseBodyConverter:362 , Retrofit (retrofit2) responseBodyConverter:345 , Retrofit (retrofit2) createResponseConverter:124 , HttpServiceMethod (retrofit2) parseAnnotations:85 , HttpServiceMethod (retrofit2) parseAnnotations:39 , ServiceMethod (retrofit2) loadServiceMethod:202 , Retrofit (retrofit2) invoke:160 , Retrofit$1 (retrofit2) getPage:-1 , $Proxy0 (jdk.proxy1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public <T> Converter<ResponseBody, T> nextResponseBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { int start = converterFactories.indexOf(skipPast) + 1 ; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter<ResponseBody, ?> converter = converterFactories.get (i).responseBodyConverter(type, annotations, this ); if (converter != null ) { return (Converter<ResponseBody, T>) converter; } } }
走到在我们注册的GsonConverterFactory 里面的responseBodyConverter实现里面
1 2 3 4 5 6 7 8 9 10 11 12 public static GsonConverterFactory create(Gson gson) { @Override public Converter<ResponseBody, ?> responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get (type)); return new GsonResponseBodyConverter<>(gson, adapter); } }
最终走到com.google.gson.Gson#getAdapter(com.google.gson.reflect.TypeToken) 获取到一个TypeAdapter