Retrofit 注解参数详解
轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/121000230
本文出自【趙彥軍的博客】
系列文章推薦:
Android Flow遇見Retrofit網絡請求實踐
Android Kotlin協程和Retrofit結合使用
Retrofit 注解參數詳解
文章目錄
- GET
- @Path
- @Query
- @QueryMap
- POST
- @Body
- form表單1:@FormUrlEncoded 、@Field
- form表單2:FormBody
- @Multipart
- 上傳單個文件
- 上傳多個文件【方式一】
- 上傳多個文件【方式二】
- 復核參數
- @Header
- 添加 Header 方式一
- 添加 Header 方式二
- 添加 Header 方式三:攔截器
- 添加 Header 方式四:Request
- 拓展
對Retrofit已經使用了一點時間了,是時候歸納一下各種網絡請求的service了。
下面分為 GET、POST、DELETE還有PUT的請求,說明@Path、@Query、@QueryMap、@Body、@Field的用法。
添加依賴
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 字符串
抓包看結果
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 字段
抓包看結果:
body 數據格式如下:name=zhaoyanjun&age=20
多個參數除了用多個 @Field ,還可以用 @FieldMap
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
添加 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()拓展
springboot 常見請求方式 https://blog.csdn.net/zhaoyanjun6/article/details/80404645
總結
以上是生活随笔為你收集整理的Retrofit 注解参数详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 断点续传实现原理
- 下一篇: Android Flow遇见Retrof