Retrofit 注解参数详解

2024-06-16 08:20
文章标签 参数 详解 注解 retrofit

本文主要是介绍Retrofit 注解参数详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

添加依赖

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

初始化Retrofit

val retrofit = Retrofit.Builder().baseUrl("http://api.github.com/").addConverterFactory(GsonConverterFactory.create()).build()

GET


一个简单的get请求:http://api.github.com/News

 @GET("News")Call<NewsBean> getItem();

@Path

interface ApiService {@GET("users/{user}/repos")fun listRepos(@Path("user") user: String): Call<List<Repo>>
}

创建 ApiService 实例

val service: ApiService = retrofit.create(ApiService::class.java)
service.listRepos("zyj1609wz").execute()

请求url

https://api.github.com/users/zyj1609wz/repos

抓包如下:


@Query


Query参数在URL问号之后

interface ApiService {@GET("users/{user}/repos")fun listRepos(@Path("user") user: String, @Query("sort") sort: String):Call<List<Repo>>
}

抓包如下:


@QueryMap


多个参数在URL问号之后,且个数不确定

interface ApiService {@GET("users/repos")fun listRepos(@QueryMap map: Map<String, String>): Call<List<Repo>>}


POST


@Body


body 传字符串

 @POST("users/repos")fun listRepos(@Body name: String): Call<List<Repo>

body 传对象, retrofit 会自动把对象解析成 json 字符串

@POST("users/repos")
fun listRepos(@Body user: User): Call<List<Repo>>

抓包看结果


form表单1:@FormUrlEncoded 、@Field


Form 表单提交数据, 数据也是放在 body 里面,通常 Form 表单和 @Field 注解联合使用。

Content-Type:application/x-www-form-urlencoded
使用 form表单提交数据,首先要在接口方法上添加 @FormUrlEncoded 注解。参数使用 @Field 、 @FieldMap

@POST("users/repos")
@FormUrlEncoded
fun listRepos(@Field("name") name: String): Call<List<Repo>>

抓包来看结果:

body 数据如下:name=zhaoyanjun

多个 @Field 字段

@POST("users/repos")
@FormUrlEncoded
fun listRepos(@Field("name") name: String, @Field("age") age: Int): Call<List<Repo>>

抓包看结果:

body 数据格式如下:name=zhaoyanjun&age=20

多个参数除了用多个 @Field ,还可以用 @FieldMap

@POST("users/repos")
@FormUrlEncoded
fun listRepos(@FieldMap name: Map<String, String>): Call<List<Repo>>

form表单2:FormBody
出了上面的 @FormUrlEncoded 我们还可以使用 FormBody 的方式提交。

首先定义接口:

@POST("users/repos")
fun listRepos(@Body body: RequestBody): Call<List<Repo>>

构建 FormBody

val body = FormBody.Builder().add("name", "zhaoyanjun").add("age", "20").build()service.listRepos(body).execute()

结果如下:

可以看到 Content-Type: application/x-www-form-urlencoded
body 参数是:name=zhaoyanjun&age=20

完美实现 form 表单提交数据。

@Multipart


其实无论什么库,只要是发送 Http 请求,都得遵守 Http 协议,所以熟悉协议内容对理解库原理、调试是有很大帮助的。

Http 上传协议为 MultiPart。下面是通过抓包获取的一次多文件+文本的上传消息,每行前面的行数是为了标注说明方便加上的,实际请求中没有。

上传单个文件

@POST("find")
@Multipart
fun listRepos(@Part part: MultipartBody.Part): Call<List<Repo>>

使用:

val file = File(externalCacheDir?.absolutePath + File.separator + "123.txt")
val requestFile = file.asRequestBody()
//创建 Part
val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile)//发起请求
service.listRepos(filePart).execute()

抓包看结果:

Content-Type: multipart/form-data; boundary=fa722b45-62ed-4481-a9fa-8b5812686d0c


上传多个文件

【方式一】
第一种方式, 写多个 MultipartBody.Part ,比如:

@POST("find")
@Multipart
fun listRepos(@Part part: MultipartBody.Part, @Part part2: MultipartBody.Part): Call<List<Repo>>

使用:

//创建第一个 Part
val file = File(externalCacheDir?.absolutePath + File.separator + "123.txt")
val requestFile = file.asRequestBody()
val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile)//创建第二个 Part
val file2 = File(externalCacheDir?.absolutePath + File.separator + "456.txt")
val requestFile2 = file2.asRequestBody()
val filePart2 = MultipartBody.Part.createFormData("file2", file2.name, requestFile2)//执行
service.listRepos(filePart, filePart2).execute()

抓包看结果:

上传多个文件【方式二】

@POST("find")
fun listRepos(@Body body: MultipartBody): Call<List<Repo>>

使用

//创建第一个 Part
val file = File(externalCacheDir?.absolutePath + File.separator + "123.txt")
val requestFile = file.asRequestBody()
val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile)//创建第二个 Part
val file2 = File(externalCacheDir?.absolutePath + File.separator + "456.txt")
val requestFile2 = file2.asRequestBody()
val filePart2 = MultipartBody.Part.createFormData("file2", file2.name, requestFile2)//构建 body 
val body = MultipartBody.Builder().setType(MultipartBody.FORM)// .addFormDataPart("file", file.name, requestFile)    .addPart(filePart)//  .addFormDataPart("file2", file2.name, requestFile2)           .addPart(filePart2).build()//发起请求
service.listRepos(body).execute()

复核参数
构建普通参数的 Part

val part = MultipartBody.Part.createFormData("age", "20")//或者
val body = MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("age", "20").build()

@Header


添加 Header 方式一

@POST("find")
fun listRepos(@Header("Accept-Encoding") encoding: String): Call<List<Repo>>

抓包看结果

添加多个 Header , 使用 @HeaderMap

@POST("find")
fun listRepos(@HeaderMap headers: Map<String, String>): Call<List<Repo>>

添加 Header 方式二
单个参数

@POST("find")
@Headers("token:zhaoyanjun")
fun listRepos(): Call<List<Repo>>

多个参数

@Headers("name:zhaoyanjun", "age:20")
@POST("find")
fun listRepos(): Call<List<Repo>>

添加 Header 方式三:拦截器

private val client = OkHttpClient.Builder().addInterceptor(HeaderInterceptor()).build()private val retrofit = Retrofit.Builder().baseUrl("http://10.8.67.211:8080").client(client).addConverterFactory(GsonConverterFactory.create()).build()class HeaderInterceptor : Interceptor {override fun intercept(chain: Interceptor.Chain): okhttp3.Response {val oldRequest = chain.request()val builder = oldRequest.newBuilder()builder.addHeader("name", "zhaoyanjun")builder.addHeader("age", "20")val request = builder.build()return chain.proceed(request)}
}

添加 Header 方式四:Request

val client = OkHttpClient.Builder().build()val request = Request.Builder().url("http://www..").addHeader("name", "zhaoyanjun").addHeader("age", "20").build()client.newCall(request).execute()


                        
原文链接:https://blog.csdn.net/zhaoyanjun6/article/details/121000230

这篇关于Retrofit 注解参数详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1065936

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MySQL8 密码强度评估与配置详解

《MySQL8密码强度评估与配置详解》MySQL8默认启用密码强度插件,实施MEDIUM策略(长度8、含数字/字母/特殊字符),支持动态调整与配置文件设置,推荐使用STRONG策略并定期更新密码以提... 目录一、mysql 8 密码强度评估机制1.核心插件:validate_password2.密码策略级

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

详解python pycharm与cmd中制表符不一样

《详解pythonpycharm与cmd中制表符不一样》本文主要介绍了pythonpycharm与cmd中制表符不一样,这个问题通常是因为PyCharm和命令行(CMD)使用的制表符(tab)的宽... 这个问题通常是因为PyCharm和命令行(CMD)使用的制表符(tab)的宽度不同导致的。在PyChar