一、添加依赖
在Module的build.gradle中添加如下依赖:
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.0.2'
//retrofit String的转换器
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
//retrofit Gson的转换器
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
//retrofit 返回值的adapter的转化器,为了于RxJava配合使用
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
二、Get请求
我在这里只讲Get请求和Post请求,因为其他的请求没用过。
- 1、首先我们将我们要访问的地址URL分成两个部分
如:
//我们要访问的地址
http://www.xxx.com/api/rest/session
//基地址
http://www.xxx.com/api/rest/
//剩下的部分
session
注意 :
retrofit2.0之后的baseUrl必需以/(斜线)结束,否则会报IllegalArgumentException异常
- 2、创建接口并定义方法
说明: 看见Call是不是感觉眼熟,是不是想起了Okhttp3,retrofit默认返回的就是Call < ResponseBody>类型(okhttp3.ResponseBody这个包);至于怎么转变为想要的类型接下来慢慢说。
/**
*
* 注解说明:
*
* 标记:
*
* 1、FormUrlEncoded 注解:表示请求体是一个Form表单;
*
* 2、Multipart 注解:表示请求体是一个支持文件上传的Form表单;
*
* 3、Streaming 注解:表示响应体的数据用流的形式返回,如果,没有用该注解,默认会吧数据存在内存,之后通过流读取数据也是读内存中的数据,如果数据比较大,建议使用该注解。
*
* 参数:
*
* 1、Headers:用于添加请求头
*
* 2、Header:用于添加不固定值的Header
*
* 3、Body:用于非表单请求体
*
* 4、Field、FieldMap、Part、PartMap:用于表单字段
*
* Field、FieldMap与FormUrlEncoded配合使用;
* Part、PartMap与Multipart配合使用,适合有文件上传的情况;
*
* FieldMap:接受的类型为Map<String,String>;
* PartMap默认接受的类型为Map<String,RequestBody>.
*
* 5、Path、Query、QueryMap、Url:用于URL
*
* Query、QueryMap中的数据体现在URL上,Field、FieldMap的数据是请求体,但是两者生成的数据形式是一样的。
*
* @Get("")中一定要有参数,否则会报错
*/
public interface MyService {
@Headers("X-Oc-Merchant-Id:1qaz2wsx")
@GET("session")
Call<ResponseBody> getSessionResponseBody();
}
- 3、使用接口
注意:回调是主线程、主线程、主线程
/**
* 在默认情况下Retrofit只支持将HTTP的响应体转换为ResponseBody
*/
private void retrofitResponseBody() {
//得到retrofit,并设置相应的基地址,别忘了调用build()
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.xxx.com/api/rest/")
.build();
//通过retrofit得到接口
MyService myService = retrofit.create(MyService.class);
//通过接口调用刚才定义的方法,看到了吧,这个返回值为call
Call<ResponseBody> call = myService.getSessionResponseBody();
//然后和okhttp一样调用enqueue,这个是异步,这里要注意哈,回调是主线程,和okhttp不一样,切记、切记、切记
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e("------------>", "response" + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
三、Get请求,使用Converter转换ResponseBody
---->转换为String,或者Gson解析的对象
我这里说的转换为String,不单单是String,而是Call< String>,转换为对象也是同理。这里需要引入一个新的东西Converter转换器,在添加依赖的时候应该看到了,有一个转为String的转换器的依赖,官方还提供了其他的几个,这里我只添加了String和Gson的。
- 1、先看看接口
//我这个里面都添加了头,这个是我门接口的要求,可根据自己的需求添加
purlic interface MyService{
@Headers("X-Oc-Merchant-Id:dsdsdsdsds")
@GET("session")
Call<String> getSession();
@GET("session")
@Headers("X-Oc-Merchant-Id:dsdsdsdsds")
Call<Session> getSessionGson();
}
- 2、使用
步骤还是上面的那些,这里我就简化了,一只.下去了(链式)
private void retrofitGet() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.xxx.com/api/rest/")
.addConverterFactory(ScalarsConverterFactory.create())//增加返回值为String的支持
.addConverterFactory(GsonConverterFactory.create())//Gson转换器
.build();
//创建接口文件
MyService myService = retrofit.create(MyService.class);
//返回数据是String
myService.getSession().enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.e("----------->", "response" + response.body() + ",message:" + response.message() + "当前线程:" + Thread.currentThread().getName());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
//返回的数据是Session类型
myService.getSessionGson().enqueue(new Callback<Session>() {
@Override
public void onResponse(Call<Session> call, Response<Session> response) {
Session session = response.body();
Log.e("------------->", "requestbody session" + session.getData().getSession() + "success:" + response.body().getSuccess() + ",message:" + response.message());
}
@Override
public void onFailure(Call<Session> call, Throwable t) {
}
});
}
- 3、说明:
这里可以看到我在创建retrofit的时候,不光添加了基地址还多了两行
//增加返回值为String的支持 .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create()) //Gson转换器
- 4、注意:
如果返回的类型不是ResponseBody,还不加上面两句话,会报如下异常:
java.lang.IllegalArgumentException: Unable to create converter for class java.lang.String异常
四、GET请求,@Path和@Query
- 1、接口
同样我都写在了MyService中
下面的两个URL为:
http://www.xxx.com/api/rest/products?id= 65
http://www.xxx.com/api/rest/products/{product_id}//将product_id替换为65
/**
* 会将id拼接在URL后面及?id=传进来的值
* @param id
* @return
*/
@GET("products")
@Headers("X-Oc-Merchant-Id:1qaz2wsx")
Call<String> getProductDetial(@Query("id") String id);
/**
* 直接将路径中的进行替换,{xxxx}就相当于占位符,然后直接用参数替代就可以了
* @param product_id
* @return
*/
@GET("products/{product_id}")
@Headers("X-Oc-Merchant-Id:1qaz2wsx")
Call<String> getProductDetialPath(@Path("product_id")String product_id);
- 2、使用
/**
* 查询参数的设置
*
* 如果Query参数比较多,那么可以通过@QueryMap方式将所有的参数集成在一个Map统一传递
*/
private void retrofitGetQuery() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.xxx.com/api/rest/")
.addConverterFactory(ScalarsConverterFactory.create())
.build();
MyService myService = retrofit.create(MyService.class);
myService.getProductDetial("65").enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.e("------------>", "response" + response.body());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("------------>", "t" + t);
}
});
}
/**
* get请求
*
* 说明@Path和@Query的区别:
*
* 1、@Path:http://www.xxx.com/api/rest/products?id=65 ----->主要定位在路径上
*
* 2、@Query:http://www.xxx.com/api/rest/products/{product_id} (把{product_id}直接写成65) ------->主要定位在参数上
*
* {占位符}和PATH尽量只用在URL的path部分,url中的参数使用Query和QueryMap 代替
*/
private void retrofitGetPath() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.xxx.com/api/rest/")
.addConverterFactory(ScalarsConverterFactory.create())
.build();
MyService myService = retrofit.create(MyService.class);
myService.getProductDetialPath("65").enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.e("------------>", "response" + response.body());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("------------>", "t" + t);
}
});
}
五、Post请求参数为Json类型及使用@Body
- 1、接口
上面也说过,非表单的参数使用@Body
请求头我们可以添加多个
/**
* post请求参数类型是json
* @param requestBody
* @return
*/
@POST("cart?from=cart")
@Headers({
"X-Oc-Merchant-Id:1qaz2wsx",
"X-OC-SESSION:8cn12jj6bruv5iemtuq0q43461",
"Content-Type:application/json"
})
Call<String> postBody(@Body RequestBody requestBody);
- 2、使用
/**
* post请求,参数是json类型的时候
*/
private void retrofitPostJson() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.xxx.com/api/rest/")
.addConverterFactory(ScalarsConverterFactory.create())
.build();
MyService myService = retrofit.create(MyService.class);
Map<String, String> params = new HashMap<>();
params.put("product_id", "65");
params.put("quantity", "2");
params.put("option", "");
params.put("recurring_id", "0");
//使用Gson将map转为json字符串
String json = new Gson().toJson(params);
Log.e("------------>", "json" + json);
//使用okHttp中的MediaType创建RequestBody
myService.postBody(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json)).enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.e("----------->", "responseffff" + response.body());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
}
- 3、说明
在学okHttp的时候我们可以将包含普通表单、json、以及包含文件的数据,放到RequestBody中当参数,所以这里也这么使用。也就明白,接口中的参数为啥为RequestBody类型了。
六、Post请求,参数为Map及使用@FieldMap
及post的请求参数是map类型
- 1、接口
注意要加上@FormUrlEncoded标记
/**
* post请求FormUrlEncoded和FieldMap配合使用
* @param id
* @param params
* @return
*/
@FormUrlEncoded
@POST("healthplan/plans/{id}")
Call<String> postFieldMap(@Path("id") String id,@FieldMap Map<String,String> params);
- 2、使用
/**
* post请求使用@FieldMap,参数是Map类型的
*/
private void retrofitPostFieldMap() {
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.baseUrl("http://app.xxx.com/v1.0.0/")
.build();
Map<String, String> map = new HashMap<>();
map.put("nickName", "单线程");
map.put("reResourceUrl", "");
map.put("reResourceId", "");
retrofit.create(MyService.class).postFieldMap("169", map).enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.e("------------>", "response" + response.body());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("------------>", "t" + t);
}
});
}
在添加转换器的时候是不是看到了一个和那个方法长得很像的方法,那个方法就可以让你和RxAndroid 一起使用了,继续往下看吧。