1、Retrofit 注解脉络图
2、请求类
2.1.1 @GET
对应get网络请求
结合@Path、@Query、@QueryMap使用
GET后面的url中可以使用自定义的变量,如 {id}、{userId}进行占位 ,并使用 @Path("id") 、@Path("userId") 注解为 {id} 、{userId} 提供值
如下:注意形如形如“?page/xxx/id/aaa”才能使用@Path来拼接url
@GET("page/{index}/id/{id}")
Call<ImageBeans> requestImage(@Path("key") int index,@Path("id") int id);
但是可能有人会想到既然是占位符,那么下面的方式可以吗?
@GET("?app=weather.future&weaid=1&&appkey={key}")
Call<WeatherBeans> requestWeather(@Path("key") int key);
答案是不可以,会报错
java.lang.IllegalArgumentException: URL query string "app=weather.future&weaid=1&&appkey={key}" must not have replace block. For dynamic query parameters use @Query.
形如“?a=xxxx&b=xxxx&c=xxxx”的url是不能用@PATH注解来拼接的,应该使用@Query或者@QueryMap注解,如下:
@Query
1、接口定义
@GET("?")
Call<WeatherBeans> requestWeather(@Query("app") String app ,@Query("weaid") int weaid , @Query("appkey") int appkey, @Query("sign") String sign, @Query("format") String format);
2、接口使用
private void doGet() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Call<WeatherBeans> call = netService.requestWeather("weather.future", 1, 10003, "b59bc3ef6191eb9f747dd4e83c99f2a4","json");
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("temperature", bean.getDays() +"|"+bean.getTemperature());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
3、结果打印
09-08 18:40:42.951 D/temperature: 2018-09-06|27℃/18℃
09-08 18:40:42.951 D/temperature: 2018-09-07|27℃/16℃
09-08 18:40:42.951 D/temperature: 2018-09-08|27℃/15℃
09-08 18:40:42.951 D/temperature: 2018-09-09|28℃/17℃
09-08 18:40:42.951 D/temperature: 2018-09-10|28℃/18℃
09-08 18:40:42.951 D/temperature: 2018-09-11|27℃/18℃
09-08 18:40:42.951 D/temperature: 2018-09-12|27℃/17℃
@QueryMap
1、接口定义
@GET("?")
Call<WeatherBeans> requestWeather(@QueryMap Map<String, String> paramas);
2、接口使用
private void doGet2() {
Log.d("#####step", "#doGet2#");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Map paramas = new HashMap<>();
paramas.put("app","weather.future");
paramas.put("weaid","1");
paramas.put("appkey","10003");
paramas.put("sign","b59bc3ef6191eb9f747dd4e83c99f2a4");
paramas.put("format","json");
Call<WeatherBeans> call = netService.requestWeather(paramas);
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("temperature", bean.getDays() +"|"+bean.getTemperature());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
3、结果打印:
09-08 19:16:43.669 D/temperature: 2018-09-06|27℃/18℃
09-08 19:16:43.670 D/temperature: 2018-09-07|27℃/16℃
09-08 19:16:43.670 D/temperature: 2018-09-08|27℃/15℃
09-08 19:16:43.670 D/temperature: 2018-09-09|28℃/17℃
09-08 19:16:43.670 D/temperature: 2018-09-10|28℃/18℃
09-08 19:16:43.670 D/temperature: 2018-09-11|27℃/18℃
09-08 19:16:43.670 D/temperature: 2018-09-12|27℃/17℃
总结:@Query和@QueryMap注解会把参数拼接到url后面,适用于GET请求
@Url
下面使用到的实体类可以通过GsonFormat插件生成,自行先访问下面url,具体可参照:JSON转实体类 好用插件 GsonFormat
1、接口定义
@GET
Call<Movies> requestMovies(@Url String url);
2、接口使用
public final static String requestUrl = "https://api.douban.com/v2/movie/top250?start=0&count=10";
private void getRequestMovieList() {
Log.d("---------->", "doGet0");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.douban.com/v2/movie/")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Call<Movies> call = netService.requestMovies(requestUrl);
call.enqueue(new Callback<Movies>() {
@Override
public void onResponse(Call<Movies> call, Response<Movies> response) {
if (response.isSuccessful()) {
Movies beans = response.body();
String title = beans.getTitle();
Log.d("##########title", "" + title);
List<Movies.Movie> movies = beans.getSubjects();
for (Movies.Movie movie : movies) {
String name = movie.getTitle();
Log.d("##########name", "" + name);
}
}
}
@Override
public void onFailure(Call<Movies> call, Throwable t) {
}
});
}
3、结果打印
09-09 19:12:29.045 D/##########title: 豆瓣电影Top250
09-09 19:12:29.045 D/##########name: 肖申克的救赎
09-09 19:12:29.045 D/##########name: 霸王别姬
09-09 19:12:29.045 D/##########name: 这个杀手不太冷
09-09 19:12:29.045 D/##########name: 阿甘正传
09-09 19:12:29.045 D/##########name: 美丽人生
09-09 19:12:29.045 D/##########name: 泰坦尼克号
09-09 19:12:29.045 D/##########name: 千与千寻
09-09 19:12:29.045 D/##########name: 辛德勒的名单
09-09 19:12:29.045 D/##########name: 盗梦空间
09-09 19:12:29.045 D/##########name: 机器人总动员
3.1.2 @POST
对应POST请求,不过需要结合@FormUrlEncoded来使用,
比如请求下面地址(这个地址是同时支持get、post请求的):
http://api.k780.com?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
可以使用post访问,结合@Field或@FieldMap做表单提交
@Field
1、接口定义
@POST("/")
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeans(
@Field("app") String app,
@Field("weaid") String weaid,
@Field("appkey") String appkey,
@Field("sign") String sign,
@Field("format") String format);
2、接口使用
private void doPost() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Call<WeatherBeans> call = netService.requestWeatherBeans("weather.future","1","10003","b59bc3ef6191eb9f747dd4e83c99f2a4","json");
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("weather:", bean.getCitynm() +"|"+bean.getDays()+"|"+bean.getTemperature());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
3、结果输出:
09-08 19:06:42.255 北京|2018-09-06|27℃/18℃
09-08 19:06:42.255 北京|2018-09-07|27℃/16℃
09-08 19:06:42.255 北京|2018-09-08|27℃/15℃
09-08 19:06:42.255 北京|2018-09-09|28℃/17℃
09-08 19:06:42.255 北京|2018-09-10|28℃/18℃
09-08 19:06:42.255 北京|2018-09-11|27℃/18℃
09-08 19:06:42.255 北京|2018-09-12|27℃/17℃
@FieldMap
1、接口定义
@POST("/")
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeans(@FieldMap Map<String, String> fields);
2、接口使用
private void doPost1() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Map paramas = new HashMap<>();
paramas.put("app","weather.future");
paramas.put("weaid","1");
paramas.put("appkey","10003");
paramas.put("sign","b59bc3ef6191eb9f747dd4e83c99f2a4");
paramas.put("format","json");
Call<WeatherBeans> call = netService.requestWeatherBeans(paramas);
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("weather:", bean.getCitynm() +"|"+bean.getDays()+"|"+bean.getTemperature());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
3、结果输出:
09-08 19:06:42.255 北京|2018-09-06|27℃/18℃
09-08 19:06:42.255 北京|2018-09-07|27℃/16℃
09-08 19:06:42.255 北京|2018-09-08|27℃/15℃
09-08 19:06:42.255 北京|2018-09-09|28℃/17℃
09-08 19:06:42.255 北京|2018-09-10|28℃/18℃
09-08 19:06:42.255 北京|2018-09-11|27℃/18℃
09-08 19:06:42.255 北京|2018-09-12|27℃/17℃
@Body
@Body会将请求参数放到请求体中,所以适用于POST请求
@Body标签不能和@FormUrlEncoded或@Multipart标签同时使用,会报错
注释源码
翻译:如果要直接控制POST / PUT请求的请求主体(而不是作为请求参数或表单样式请求主体发送),请在服务方法参数上使用此批注。该对象将使用Retrofit实例Converter进行序列化,结果将直接设置为请求正文。
/**
* Use this annotation on a service method param when you want to directly control the request body
* of a POST/PUT request (instead of sending in as request parameters or form-style request
* body). The object will be serialized using the {@link Retrofit Retrofit} instance
* {@link Converter Converter} and the result will be set directly as the
* request body.
* <p>
* Body parameters may not be {@code null}.
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Body {
}
使用这个标签的意思是我们可以定义个实体类来封装参数,作为请求参数,简洁明了
@Body实际上是将类转换成json实体作为请求体来请求网络的,可以抓包看
1、接口定义:
public interface NetService {
@POST("/")
Call<WeatherBeans> requestWeatherBeans(@Body RequestParams parama);
class RequestParams {
public String app;
public int weaid;
public int appkey;
public String sign;
public String format;
}
}
2、接口使用
private void doPostWithBody() {
Log.d("##########", "doPostWithBody");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
//创建以@Body注解post请求参数
NetService.RequestParams params = new NetService.RequestParams();
params.app = "weather.future";
params.weaid = 1;
params.appkey = 10003;
params.sign = "b59bc3ef6191eb9f747dd4e83c99f2a4";
params.format = "json";
Call<WeatherBeans> call = netService.requestWeatherBeans(params);
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("weather:", bean.getCitynm() + "|" + bean.getDays() + "|" + bean.getTemperature());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
3、结果打印
由于@Body实际上是将类转换成json实体作为请求体来请求网络,一时间没找到可以接受json格式的请求体作为参数的网络,因此这里这是从形式说明怎么使用,这是没有问题,后面等我找到了可以公开访问的url地址再补上
常见错误1:@Body parameters cannot be used with form or multi-part encoding
注意:相比较前面的post请求去掉了@FormUrlEncoded注解,否则会报错:
为什么会报错,快捷键跟踪一下@Body被使用的地方,在ServiceMethodlei中有源码如下:
部分
else if (annotation instanceof Body) {
if (isFormEncoded || isMultipart) {
throw parameterError(p,
"@Body parameters cannot be used with form or multi-part encoding.");
}
if (gotBody) {
throw parameterError(p, "Multiple @Body method annotations found.");
}
Converter<?, RequestBody> converter;
try {
converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations);
} catch (RuntimeException e) {
// Wide exception range because factories are user code.
throw parameterError(e, p, "Unable to create @Body converter for %s", type);
}
gotBody = true;
return new ParameterHandler.Body<>(converter);
}
常见错误2:@Unable to create @Body converter for %s
在遇到对请求参数或者请求结果加密处理的时候GsonConverterFactory可能无法满足我们的需求,因此需要重写GsonConverterFactory,这时候需要重写两个方法如下,注意两个方法必须同时重写,否则可能就报这个错误
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
2.1.3 @PUT
提交资源或者更新资源
将资源提交给服务器,如果请求的url地址已经在服务器上存在对应的资源了,则put请求提交的实体则会对其进行修改。
这里就不举例了
2.1.4 @DELETE
DELETE方法请求源服务器删除Request-URI标识的资源。如果响应包括描述状态的实体,则成功响应应为200(OK),如果操作尚未执行,则应为202(已接受);如果操作已颁布但响应不包括,则应为204(无内容)一个实体。
DELETE方法与PUT相对应。
这里就不举例了
2.1.5 @PATCH
该请求是对PUT请求的补充,用于局部更新资源
这里就不举例了
2.1.6 @HEAD
@HEAD用来表示http请求中的head请求,head请求来源是HTTP1.0,HTTP1.0有三种请求方式GET、POST、HEAD。HTTP1.1新增了PUT、DELETE、OPTIONS、 TRACE 、CONNECT。
HEAD方法与GET相同,只是服务器不能在响应中返回消息体。响应HEAD请求的HTTP头中包含的元信息应该与响应GET请求时发送的信息相同。该方法可用于获得关于请求所暗示的实体的元信息,而无需转移实体主体本身。此方法通常用于测试超文本链接的有效性,可访问性和最近的修改。
对HEAD请求的响应是可缓存的,因为响应中包含的信息可用于从该资源更新先前缓存的实体。如果新字段值指示缓存的实体与当前实体不同(如Content-Length,Content-MD5,ETag或Last-Modified中的更改所示),则缓存必须将缓存条目视为陈旧。
使用场景:
- 检查资源的有效性
- 检查超链接的有效性
- 检查网页是否被串改
- 用于自动搜索机器人获取网页的标志信息,获取rss种子信息,或者传递安全认证信息等
@Headers({"Content-Type: application/json", "Cache-Control: max-age=360000"})
Call<WeatherBeans> requestWeatherBeansByHeaders();
2.1.7 @OPTIONS
OPTIONS请求主要用途有两个:
- 获取服务器支持的HTTP请求方法,是黑客喜欢使用的方法。
- 用来检查服务器的性能,如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
这里就不举例说明了
2.1.8 @HTTP
@HTTP请求,可配置成以上7种中的任意一种
@HTTP配置get请求
1、接口定义
@HTTP(method = "GET", path = "?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json", hasBody = false)
Call<WeatherBeans> requestWeatherBeansByHttp();
2、接口使用
private void doHttp() {
Log.d("##########", "doHttp");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Call<WeatherBeans> call = netService.requestWeatherBeansByHttp();
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("weather:", bean.getCitynm() + "|" + bean.getDays() + "|" + bean.getTemperature());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
3、结果打印
09-09 11:59:30.099 北京|2018-09-07|27℃/16℃
09-09 11:59:30.099 北京|2018-09-08|27℃/15℃
09-09 11:59:30.099 北京|2018-09-09|27℃/16℃
09-09 11:59:30.099 北京|2018-09-10|28℃/18℃
09-09 11:59:30.099 北京|2018-09-11|27℃/18℃
09-09 11:59:30.100 北京|2018-09-12|27℃/17℃
09-09 11:59:30.100 北京|2018-09-13|28℃/18℃
@HTTP配置post请求
注意:
1)配置POST请求必须结合@FormUrlEncoded使用,否者会报错
2)hasBody必须配置为true,否则报错
java.lang.IllegalArgumentException: FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).
for method NetService.requestWeatherBeansByHttpPost
1、接口定义
@HTTP(method = "POST", path = "?", hasBody = true)
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeansByHttpPost(@FieldMap Map<String, String> paramas);
2、接口使用
private void doHttpPost() {
Log.d("##########", "doHttpPost");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Map paramas = new HashMap<>();
paramas.put("app", "weather.future");
paramas.put("weaid", "1");
paramas.put("appkey", "10003");
paramas.put("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4");
paramas.put("format", "json");
Call<WeatherBeans> call = netService.requestWeatherBeansByHttpPost(paramas);
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("weather:", bean.getCitynm() + "|" + bean.getDays() + "|" + bean.getTemperature());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
3、结果打印
09-09 12:12:46.411 北京|2018-09-07|27℃/16℃
09-09 12:12:46.411 北京|2018-09-08|27℃/15℃
09-09 12:12:46.411 北京|2018-09-09|27℃/16℃
09-09 12:12:46.411 北京|2018-09-10|28℃/18℃
09-09 12:12:46.412 北京|2018-09-11|27℃/18℃
3、参数类注解
该类注解主要是结合上面8中注解使用,上面也都出现过部分,下面是总结
@Query、@QueryMap、@Url 、@Field、@FieldMap、@Body、@Headers 、@Header、@Part 、@PartMap 、@Path
public interface NetService {
@GET("?")
Call<WeatherBeans> requestWeather(@Query("app") String app, @Query("weaid") int weaid, @Query("appkey") int appkey, @Query("sign") String sign, @Query("format") String format);
@GET("?")
Call<WeatherBeans> requestWeather(@QueryMap Map<String, String> paramas);
@GET
Call<Movies> requestMovies(@Url String url);
@POST("/")
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeans(
@Field("app") String app,
@Field("weaid") String weaid,
@Field("appkey") String appkey,
@Field("sign") String sign,
@Field("format") String format);
@POST("/")
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeans(@FieldMap Map<String, String> fields);
@POST("/")
Call<WeatherBeans> requestWeatherBeans(@Body RequestParams parama);
class RequestParams {
public String app;
public int weaid;
public int appkey;
public String sign;
public String format;
}
@Headers({"Content-Type: application/json", "Cache-Control: max-age=360000"})
@HTTP(method = "GET", path = "?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json", hasBody = false)
Call<WeatherBeans> requestWeatherBeansByHeaders();
@GET("login")
Call<UserInfo> login(@Header("Authorization") String authorization);
@HTTP(method = "POST", path = "?", hasBody = true)
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeansByHttpPost(@FieldMap Map<String, String> paramas);
@Multipart
@POST("web/shrink")
Call<ResponseBody> uploadFile(@Part("description") RequestBody description, @Part MultipartBody.Part file);
@Multipart
@POST("web/shrink")
Call<ResponseBody> uploadFile(@PartMap Map<String, RequestBody> params);
@GET("back_pic/03/70/72/5257b6c12d89875.jpg!r850/fw/{id}")
Call<ResponseBody> getImage(@Path("id") int id);
}
@Part 、@PartMap
接口定义
/**
* 上传图文
* @param description
* @param file
* @return
*/
@Multipart
@POST("web/shrink")
Call<ResponseBody> uploadFile(@Part("description") RequestBody description, @Part MultipartBody.Part file);
/**
* 上传一张图片
* @param file
* @return
*/
@Multipart
@POST("web/shrink")
Call<ResponseBody> uploadFile(@Part() RequestBody file);
/**
* 上传一张图片 另一种写法
* @param file
* @return
*/
@Multipart
@POST()
Call<ResponseBody> uploadFile(@Url String url, @Part() RequestBody file);
/**
* 上传数量确定的多张图片
* @param description
* @param img1
* @param img2
* @param img3
* @return
*/
@POST("web/shrink")
Call<ResponseBody> uploadFiles(@Part("filename") String description,
@Part("img\"; name=\"img1.png") RequestBody img1,
@Part("img\"; name=\"img2.png") RequestBody img2,
@Part("img\"; name=\"img3.png") RequestBody img3);
/**
* 上报数量不定的多张图片 版本1
* @param params
* @return
*/
@Multipart
@POST("web/shrink")
Call<ResponseBody> uploadFile(@PartMap Map<String, RequestBody> params);
/**
* 上报数量不定的多张图片 版本2
* @param url
* @param maps
* @return
*/
@Multipart
@POST()
Call<ResponseBody> uploadFiles( @Url String url, @PartMap() Map<String, RequestBody> maps);
使用:
private void doUpload() {
Log.d("---------->", "doUpload");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://tinypng.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
File file = getFile();
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part 和服务端约定好Key,这里的part name是用image
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
// 添加上传文件描述
String descriptionString = "文件描述:这是一张照片";
RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString);
Call<ResponseBody> call = netService.uploadFile(description, body);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
ResponseBody responseBody = response.body();
Log.d("doUpload responseBody", responseBody.string());
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.d("doUpload responseBody", "failed");
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("doUpload responseBody", "onFailure");
}
});
}
@Path
1、接口定义
@GET("back_pic/03/70/72/5257b6c12d89875.jpg!r850/fw/{id}")
Call<ResponseBody> getImage(@Path("id") int id);
2、接口使用
private void doGetImage() {
Log.d("#####step", "#doGetImage#");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://bpic.588ku.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Call<ResponseBody> call = netService.getImage(800);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
Log.d("#####step", "#isSuccessful#");
} else {
Log.d("#####step", "#Failure#");
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("#####step", "#onFailure#");
}
});
}
3、结果打印
/#####step: #isSuccessful#
4、标记类
4.1、@FormUrlEncoded
主要是做表单提交,与@POST结合使用
4.2、@Multipart
主要是与@POST结合使用做文件的上传
4.3、@Streaming
主要做大文件下载
@GET
@Streaming
Call<ResponseBody> downloadImage(@Url String url);