Retrofit2 json请求

使用Retrofit2进行json请求是个老生常谈的问题,值得单独水一期

总体来说,Retrofit2传递json有三种方法

首先初始化一下,这里使用官方提供的GsonConverter

implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
val retrofit = Retrofit.Builder().client(OkHttpClient.Builder().build())
            .baseUrl(baseUri)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

一、直接传递body

这种方法是最常见,写法最复杂的方法

首先,create里添加一个接收body参数的方法

    @POST(data)
    suspend fun data1(@Body body: RequestBody):Bean

然后写一个string转body的方法

fun jsonToBody(json:String) = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json)

接下来就可以愉快地写代码了

val json = "这是要传递的json"
val data = Retrofit.data1(jsonToBody(json))

二、传递对象

这种方法需要在Converter里把对象转换成body,当然官方提供的Converter(包括我们现在使用的GsonConverter)已经帮我们做好这一步,所以我们直接使用就行

    @POST(data)
    suspend fun data3(@Body any:Any):Bean
class Data(val name:String)            
val map = mutableMapOf<String,Any>()
map["参数1"] = 1
map["参数2"] = '2'
map["参数3"] = "3"
map["参数4"] = Data("小明")
val data = Retrofit.data3(map)

或
class PostData(val data1:String,val data2:Int)
val data = Retrofit.data3(PostData("参数1",2))

这里Any可以传任何一个非String类型的值,只要你能确保传入的参数能序列化成你需要的json就行,传入的对象会在Converter里被转换成Body

三,传递String

很多时候,我们希望直接传递String json,而不是在传递前还得考虑序列化的问题

我们希望有这样一个方法:

    @POST(data)
    suspend fun data2(@Body json:String):Bean

然而上面已经说了,官方提供的Converter并不支持String序列化,因此我们需要自己写一个Converter,并且重写requestBodyConverter方法

class StringConverterFactory: Converter.Factory(){
    override fun responseBodyConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<ResponseBody, *>? {
        if(type == String::class.java)
            return StringResponseConverter()
        return super.responseBodyConverter(type, annotations, retrofit)
    }

    override fun requestBodyConverter(
        type: Type,
        parameterAnnotations: Array<Annotation>,
        methodAnnotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, RequestBody>? {
        if(type == String::class.java){
            return StringRequestConverter()
        }else
        return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit)
    }
    class StringResponseConverter: Converter<ResponseBody, String> {
        override fun convert(value: ResponseBody): String? {
            return value.string()
        }

    }
    class StringRequestConverter: Converter<String, RequestBody>{
        override fun convert(value: String): RequestBody =
            RequestBody.create(MediaType.parse("application/json; charset=utf-8"),value)
    }
}
        val retrofit = Retrofit.Builder().client(OkHttpClient.Builder().build())
            .baseUrl(baseUri)
            .addConverterFactory(StringConverterFactory())
            .addConverterFactory(GsonConverterFactory.create())
            .build()

这样,Retrofit2就具备了把String转换成body的能力了,然后就可以这样写

    @POST(data)
    suspend fun data2(@Body json:String):Bean

    val json = "这是要传递的json"
    val data = retrofit.data2(json)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值