• 五月
  • 14
  • load

【Retrofit第二篇】Converter,具有灵魂的请求 2021-05-14 20:48:43

在介绍@Body的时候,我介绍了addConverterFactory这东西,这是什么?

这个是请求转换器,如果你掌握了这东西,retrofit对你来说就开始逐渐好用了。

我们提交body时,没有加上ScalarsConverterFactory.create()就出错了,那么,ScalarsConverterFactory是什么东西?

你可以理解它是通用转换器,直接ctrl进去不难发现,就是把基础数据类型和字符串转成字符串

然后又转成bytes数组,存放到body里

这意味着,这个转换器不能转换我们自己定义的对象(就是想转它也不知道要转成什么)

“我大概知道有这么一个东西了,如果我要把对象转换成json,难道要自己写转换器?”

一般通用转换器在github都能找到,不过官方就提供了一个方案,用gson。

还记得一开始我们引入的依赖吗?其中就有gson,使用方法也很简单

addConverterFactory(GsonConverterFactory.create())

这个时候,你的数据类就能解析成json并用于请求了

最终请求:

假设服务器视为请求成功,并只返回了1

那么会请求成功,日志会输出1

如果你把Call的泛型改成Int会怎样?

没问题,response的body会因为你的泛型而改变,而GsonConverterFactory实际是在gson工作,而gson会解析基本数据类型。

即使你的Call泛型放着一个数据类,只要服务器返回的json和你的数据类对得上,就能解析。

 

假设你家服务端,返回的东西都是密文,解密后才是json,该怎么办?

这个时候,就得自定义转换器了。

创建一个类,这里就叫DecompressConverterFactory好了,继承Converter.Factory,得到如下基本结构

根据这两个方法得知,我们还需要写两个继承Converter的类,用于处理过程。

假设,你家服务端数据明文是 {"name":"张三","age":24}

而密文数据是(用base64编码模拟一下加密):eyJuYW1lIjoi5byg5LiJIiwiYWdlIjoyNH0=

接收数据也需要加密,那么就这么做

然后就是调用:

最终请求:

服务端返回:

日志输出:

提交的明文: {"age":1,"name":"name"}

提交的密文: eyJhZ2UiOjEsIm5hbWUiOiJuYW1lIn0=

解析服务端内容: {"name":"张三","age":24}

search: Test(name=张三, age=24)

在转换器的帮助下,我们就不用关心格式化的问题了。

至于转换器还有什么写法,建议阅读下别人是如何写的,例如GsonConverterFactory,内容不多,有助于自己理解。

 

直接阅读Converter.Factory源码时可以发现,它还有一个抽象方法,叫stringConverter,这是什么?

根据注释说明可以了解,它是转换@Field,@FieldMap,@Header,@HeaderMap,@Path,@Query,@QueryMap这些非@body请求参数注解的。

也就是说,你仅用@Body的情况下,stringConverter是不会回调的。

 

以@Field为例,我们意图是传递一个对象,它自动给我们转换成base64,并发送给服务器,那么就这么写。

data class:

请求方式:

转换器:

最终请求

可见,即使我们传了对象,也自动给我们转码了。

注意:

1.base64可能会有等号,这个转换若出现了等号,会自动转码为%3D

2.只要你写了转换器,responseBodyConverter必须要实现,否则会报错

 

原创文章,转载请注明出处

正在加载评论...

0 / 240

警告

确定