retrofit2的参数详解

参数类注解

/**
  * [Retrofit注解详解 之 FormUrlEncoded/Field/FieldMap/Multipart/Part/PartMap注解]源码
  */
  public class Example03 {
  public interface BlogService {
   
  /**
  * {@link FormUrlEncoded} 表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
  * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
  */
  @POST("/form")
  @FormUrlEncoded
  Call<ResponseBody> testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);
   
  /**
  * Map的key作为表单的键
  */
  @POST("/form")
  @FormUrlEncoded
  Call<ResponseBody> testFormUrlEncoded2(@FieldMap Map<String, Object> map);
   
   
  /**
  * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
  * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
  */
  @POST("/form")
  @Multipart
  Call<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);
   
  /**
  * PartMap 注解支持一个Map作为参数,支持 {@link RequestBody } 类型,
  * 如果有其它的类型,会被{@link retrofit2.Converter}转换,如后面会介绍的 使用{@link com.google.gson.Gson} 的 {@link retrofit2.converter.gson.GsonRequestBodyConverter}
  * 所以{@link MultipartBody.Part} 就不适用了,所以文件只能用<b> @Part MultipartBody.Part </b>
  */
  @POST("/form")
  @Multipart
  Call<ResponseBody> testFileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);
   
  @POST("/form")
  @Multipart
  Call<ResponseBody> testFileUpload3(@PartMap Map<String, RequestBody> args);
  }
   
  public static void main(String[] args) {
  Retrofit retrofit = new Retrofit.Builder()
  .baseUrl("http://localhost:4567/")
  .build();
   
  BlogService service = retrofit.create(BlogService.class);
   
   
  // 演示 @FormUrlEncoded 和 @Field
  Call<ResponseBody> call1 = service.testFormUrlEncoded1("怪盗kidou", 24);
  ResponseBodyPrinter.printResponseBody(call1);
   
   
  //===================================================
   
  // 演示 @FormUrlEncoded 和 @FieldMap
  // 实现的效果与上面想同
  Map<String, Object> map = new HashMap<>();
  map.put("username", "怪盗kidou");
  map.put("age", 24);
  Call<ResponseBody> call2 = service.testFormUrlEncoded2(map);
  ResponseBodyPrinter.printResponseBody(call2);
   
   
  //===================================================
   
   
  MediaType textType = MediaType.parse("text/plain");
  RequestBody name = RequestBody.create(textType, "怪盗kidou");
  RequestBody age = RequestBody.create(textType, "24");
  RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容");
   
  // 演示 @Multipart 和 @Part
  MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
  Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);
  ResponseBodyPrinter.printResponseBody(call3);
   
  //===================================================
  // 演示 @Multipart 和 @PartMap
  // 实现和上面同样的效果
  Map<String, RequestBody> fileUpload2Args = new HashMap<>();
  fileUpload2Args.put("name", name);
  fileUpload2Args.put("age", age);
  //这里并不会被当成文件,因为没有文件名(包含在Content-Disposition请求头中),但上面的 filePart 有
  //fileUpload2Args.put("file", file);
  Call<ResponseBody> call4 = service.testFileUpload2(fileUpload2Args, filePart); //单独处理文件
  ResponseBodyPrinter.printResponseBody(call4);
   
  //===================================================
  // 还有一种比较hack的方式可以实现文件上传,
  // 上面说过被当成文件上传的必要条件就是 Content-Disposition 请求头中必须要有 filename="xxx" 才会被当成文件
  // 所有我们在写文件名的时候可以拼把 filename="XXX" 也拼接上去,
  // 即文件名变成 表单键名"; filename="文件名 (两端的引号会自动加,所以这里不加)也可以实现,但是不推荐方式
   
  Map<String, RequestBody> fileUpload3Args = new HashMap<>();
  fileUpload3Args.put("name",name);
  fileUpload3Args.put("age",age);
  fileUpload3Args.put("file\"; filename=\"test.txt",file);
  Call<ResponseBody> testFileUpload3 = service.testFileUpload3(fileUpload3Args);
  ResponseBodyPrinter.printResponseBody(testFileUpload3);
  }
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值