Retrofit 注解参数详解

news2024/11/24 7:16:23

添加依赖

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1828146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度遍历-求矩阵最长递增路径

一、问题描述 二、解题思路 和深度遍历-求岛屿数量的思路一致&#xff0c;不过这里不需要设置判断是否产生访问过的boolean二维数组了&#xff0c;因为在这个题目里面是求递增序列&#xff0c;下一个元素只有比当前元素大才会往前走&#xff0c;即使在回头检查时&#xff0c;发…

大模型网信办备案全网最详细流程【附附件】

本文要点&#xff1a;大模型备案最详细说明&#xff0c;大模型备案条件有哪些&#xff0c;《算法安全自评估报告》模板&#xff0c;大模型算法备案&#xff0c;大模型上线备案&#xff0c;生成式人工智能(大语言模型)安全评估要点&#xff0c;网信办大模型备案。 大模型备案安…

Spring学习笔记(九)简单的SSM框架整合

实验目的 掌握SSM框架整合。 实验环境 硬件&#xff1a;PC机 操作系统&#xff1a;Windows 开发工具&#xff1a;idea 实验内容 整合SSM框架。 实验步骤 搭建SSM环境&#xff1a;构建web项目&#xff0c;导入需要的jar包&#xff0c;通过单元测试测试各层框架搭建的正确…

SpringBootWeb 篇-入门了解 Spring Cache 、Spring Task 与 WebSocket 框架

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Spring Cache 概述 1.1 Spring Cache 具体使用 1.1.1 引入依赖 1.1.2 Spring Cache 相关注解的介绍 2.0 Spring Task 概述 2.1 cron 表达式 2.2 Spring Task 使用…

平安:PostgreSQL开发运维案例

PostgreSQL作为功能强大且开源的关系型数据库管理系统&#xff0c;广泛应用于各种开发和运维场景中。本文将探讨PostgreSQL在开发和运维中的最佳实践&#xff0c;涵盖环境搭建、性能优化、安全管理和备份恢复等关键环节&#xff0c;旨在帮助读者充分发挥PostgreSQL的优势&#…

MFC工控项目实例之四在调试目录下创建指定文件夹

承接专栏《MFC工控项目实例之三theApp变量传递对话框参数》 在调试目录Debug下创建DATA、LIB、TEMP三个文件夹 1、SEAL_PRESSURE.h中添加代码 class CSeatApp : public CWinApp { ... public:CString m_Path;CString m_DataPath,m_TempPath,m_LibPath; ... };2、SEAL_PRESSURE…

机器人、人工智能相关领域 news/events (专栏目录)

Some Insights 一些机器人、人工智能或相关领域的news、events等 1. 智能制造 - 你需要了解的 10 个基本要素 2. 现实世界中的人工智能&#xff1a;工业制造的 4 个成功案例研究 3. 企业使用人工智能情况调查 4. 未来工厂中的人工智能&#xff1a;人工智能加速制造成果规模…

[C++ STL] vector 详解

标题&#xff1a;[C STL] vector 详解 水墨不写bug 目录 一、背景 二、vector简介 三、vector的接口介绍 &#xff08;1&#xff09;默认成员函数接口 i&#xff0c;构造函数&#xff08;constructor&#xff09; ii&#xff0c;析构函数&#xff08;destructor&#xff0…

Matlab|基于手肘法的kmeans聚类数的精确识别【K-means聚类】

主要内容 在电力系统调度研究过程中&#xff0c;由于全年涉及的风、光和负荷曲线较多&#xff0c;为了分析出典型场景&#xff0c;很多时候就用到聚类算法&#xff0c;而K-means聚类就是常用到聚类算法&#xff0c;但是对于K-means聚类算法&#xff0c;需要自行指定分类数&…

【深度学习】TCN,An Empirical Evaluation of Generic Convolutional【二】

文章目录 膨胀卷积什么是膨胀卷积膨胀卷积公式PyTorch代码 从零开始手动实现一个1D膨胀卷积&#xff0c;不使用PyTorch的nn.Conv1d1. 基本概念2. 手动实现1D膨胀卷积 TCN结构如何使用TCN源码说明1. Chomp1d 类2. TemporalBlock 类3. TemporalConvNet 类 使用方法 膨胀卷积 什么…

Unity 3D 物体的Inspector面板

1、Transform&#xff1a;位置、旋转、大小 2、Mesh Filter&#xff1a;物体的形状 3、Mesh Renderer&#xff1a;物体渲染&#xff08;物体的衣服&#xff09; 4、Collider&#xff1a;碰撞体

python错题(1)

字典中min&#xff0c;max最后比较的是键&#xff0c;输出的是键

python12 元组类型

元组用 () 声明&#xff0c;注意如果只有一个元素时要在元素后面加个 逗号, 否则不是类型就不是元组了。 声明方式2内置函数声明 data tuple(helloworld); 元组是不可变列表&#xff0c; 元组可以使用序列的所有功能。具体可以看我以前序列的文章 元组里的元素可以是多种数据类…

Python爬虫JS逆向进阶课程

这门课程是Python爬虫JS逆向进阶课程&#xff0c;将教授学员如何使用Python爬虫技术和JS逆向技术获取网站数据。学习者将学习如何分析网站的JS代码&#xff0c;破解反爬虫机制&#xff0c;以及如何使用Selenium和PhantomJS等工具进行模拟登录和数据抓取。课程结合实例演练和项目…

物流货运单怎么打印,佳易王货物运单打印查询统计管理系统操作教程

物流货运单怎么打印&#xff0c;佳易王货物运单打印查询统计管理系统操作教程 一、前言 以下软件操作教程以&#xff0c;佳易王物流货运单管理软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 软件操作教程 1、物流开单点击导航栏 物流开单…

C++ 58 之 计算器案例

虚函数,vitual function C动态多态性是通过虚函数来实现的&#xff0c;虚函数允许子类&#xff08;派生类&#xff09;重新定义父类&#xff08;基类&#xff09;成员函数&#xff0c;而子类&#xff08;派生类&#xff09;重新定义父类&#xff08;基类&#xff09;虚函数的做…

非接触式装配监控技术实现对装配工作站操作的实时动作识别和定位

当今快速发展的工业领域&#xff0c;智能制造作为第四次工业革命的核心&#xff0c;正引领着生产方式的革新。智能制造的关键在于实时监控和数据分析&#xff0c;这不仅能优化生产流程&#xff0c;还能显著提升产品质量和生产效率。其中&#xff0c;装配操作的实时监控对于制造…

配置Linux DNS服务器作为自己的windows 的 DNS服务器和 配置遇到的问题

安装DNS 库 和 DNS工具&#xff1a; # bind 是用于创建 dns服务的&#xff0c; bind-utils是用于测试DNS服务的工具 yum -y install bind bind-utils配置主配置文件&#xff1a; # 下载好后就已经有DNS服务&#xff0c;但是需要你自己去配置DNS服务信息# 配置主配置文件 [rootl…

Parallelize your massive SHAP computations with MLlib and PySpark

https://medium.com/towards-data-science/parallelize-your-massive-shap-computations-with-mllib-and-pyspark-b00accc8667c (能翻墙直接看原文&#xff09; A stepwise guide for efficiently explaining your models using SHAP. Photo by Pietro Jeng on Unsplash Int…