Retrofit2简单使用
1,添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.5.0' //Retrofit依赖
implementation 'com.squareup.okhttp3:okhttp:3.10.0' //Okhttp依赖
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'//可选依赖,解析json字符所用
2,新建javabean类,解析并保存请求到的数据
public class Translation {
private int status;
private Content content;
private static class Content{
private String from;
private String to;
private String vendor;
private String out;
private int errNo;
}
public String getFrom() {return content.from;}
public String getTo() {return content.to;}
public String getVendor() {return content.vendor;}
public String getOut() {return content.out;}
public int getErrNo() {return content.errNo;}
public void show(){
LogUtil.show(status+"");
LogUtil.show(content.from);
LogUtil.show(content.to);
LogUtil.show(content.vendor);
LogUtil.show(content.out);
LogUtil.show(content.errNo+"");
}
}
3,新建java接口,实现请求
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
public interface GetRequest_Interface {
//get请求,{user}是要传入的参数,@Path("user"),表示将传入的参数加到url上
@GET("api/columns/{user}")
Call<ResponseBody> getAuthor(@Path("user") String user); //获取请求获取的数据
//@GET表示GET请求,()内为url
@GET("ajax.php?a=fy&f=auto&t=auto&w=hello%20world")
Call<Translation> getCall();
//采用@Post表示Post方法进行请求(传入部分url地址)
// 采用@FormUrlEncoded注解的原因:API规定采用请求格式x-www-form-urlencoded,即表单形式
// 需要配合@Field 向服务器提交需要的字段
@POST("translate?doctype=json&jsonversion=&type=&keyfrom=&model=&mid=&imei=&vendor=&screen=&ssid=&network=&abtest=")
@FormUrlEncoded
Call<TranslationPost> getPostCall(@Field("i") String targetSentence);
}
4,使用Retrofit完成Get请求
1,初始化Retrofit获取请求对象
String URL = "https://zhuanlan.zhihu.com/";
String BASE_URL = "http://fy.iciba.com/";
//GET请求,通过URL创建Retrofit实例对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
GetRequest_Interface anInterface = retrofit.create(GetRequest_Interface.class);
//传入参数,发送请求,获取请求获取的原始json数据
Call<ResponseBody> mQingao = anInterface.getAuthor("qingao");
//get请求,通过BASE_URL创建Retrofit对象,添加json数据解析器
Retrofit mRetrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
//创建网络请求接口实例
GetRequest_Interface api = mRetrofit.create(GetRequest_Interface.class);
//发送请求,并对请求到的数据解析封装成Translation对象
Call<Translation> mCall = api.getCall();
2,请求回调,获取请求成功或失败的数据
//因为请求执行过一次后会自动关闭,再次发送请求会报错,这里先判断请求是否已经发送过
if(!mCall.isExecuted()){
mCall.enqueue(new Callback<Translation>() {
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
//response.body()获取请求返回的请求体
//处理请求成功的回调
response.body().show();
String out = response.body().getOut();
Message message = new Message();
message.what = 2;
message.obj = out;
mHandler.sendMessage(message);
}
@Override
public void onFailure(Call<Translation> call, Throwable t) {
//请求失败的回调
LogUtil.show("连接失败");
}
});
}
5,注解说明
网络请求方法
网络请求注解名称 | 解释说明 | 作用域 |
---|---|---|
@GET | 对应HTTP网络请求方法,接收网络请求url | 网络请求方法 |
@POST | 同上 | 同上 |
@PUT | 同上 | 同上 |
@DELETE | 同上 | 同上 |
@PATH | 同上 | 同上 |
@HEAD | 同上 | 同上 |
@OPTIONS | 同上 | 同上 |
@HTTP | 用于替换以上几种注释作用及拓展功能 | 同上 |
网络请求完整的url
URL = baseUrl + 网络请求接口的注释设置(path)
类型 | 具体使用 |
---|---|
path = 完整的url | 接口设置里是一个完整的url,创建Retrofit实例时不设置baseUrl |
path = 绝对路径 | url=“http://host:port/apath” 其中 path=/apath baseUrl = “http://host:port/a/b” |
path=相对路径 baseUrl=目录形式 | url="http://host:port/a/b/apath"其中 path= “apath” baseUrl=“http://host:port/a/b/” |
path=相对路径 baseUrl=文件形式 | Url="http:host:port/a/b/apth"其中 path = "apath" baseUrl=“http://host:port/a/b” |
@HTTP
在网络请求接口中通过method,path,hasBody进行设置
//GET请求,传入变量id加到path对应位置,没有请求体
//method : 网络请求方式,区分大小写
//path : 网络请求地址路径
//hasBody : 是否有请求体
//{id} 表示一个变量
@HTTP(method = "GET",path = "blog/{id}",hasBody = false)
Call<ResponseBody> getGetCall(@Path("id") int id);
标记
标记注解作用于网络请求接口文件
注解名称 | 解释说明 |
---|---|
@FormUrlEncoded | 表示请求体是一个form表单,发送form-encoded数据 每个键值对需要使用@Filed来注解键名,随后的对象需要提供值 |
@Multipart | 表示请求体是一个支持文件上传的表单,发送form-encoded数据 每个键值对使用@Part来注解键名,随后的对象需要提供值 |
@Streaming | 表示返回的数据以流的形式返回 适用于返回数据较大的场景 (如果没有使用该注解,默认将数据全部载入内存,之后获取数据也是从内存中读取) |
//表示是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
//@Field("username") 表示将String name 的取值作为username的值
@POST("/form")
@FormUrlEncoded
Call<ResponseBody> postCall(@Field("username") String name,@Field("age") int age);
//@Part后面支持三种类型:RequestBody,MultipartBody.Part,任意类型
//除了MultipartBody.Part外,其它类型都必须带上表单字段
//MultipartBody.Part中已经包含了表单字段
@POST("/form")
@Multipart
Call<ResponseBody> postCall2(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);
使用
Retrofit postRetrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
GetRequest_Interface postInterface = postRetrofit.create(GetRequest_Interface.class);
//@FormUrlEncoded
Call<ResponseBody> postCall = postInterface.postCall("eyesee", 18);
//Multipart
File file = new File("http://www.baidu.com/");
//数据解析成表单数据
RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"),"");
RequestBody name = RequestBody.create(MediaType.parse("multipart/form-data"),"eyesee");
RequestBody age = RequestBody.create(MediaType.parse("multipart/form-data"),"18");
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", body);
Call<ResponseBody> postCall2 = postInterface.postCall2(name, age, filePart);
6,网络请求参数
1,作用在请求接口的方法上
网络请求参数注解名称 | 解释说明 |
---|---|
@Headers | 添加请求头 |
@Header | 添加不固定值的请求头 |
@Body | 用于非表单请求体 |
@Filed | 向Post表单传入键值对 |
@FiledMap | 向Post表单传入键值对 |
@Part | 用于表单字段,适用于有文件上传的情况 |
@PartMap | 用于表单字段,适用于有文件上传的情况 |
@Query | 用于表单字段,功能同@Field,@FieldMap 区别在@Query的请求数据体现在URL上,@Field,@FieldMap数据体现在请求体上 但生成的数据是一致的 |
@QueryMap | 用于表单字段,功能同@Field,@FieldMap 区别在@QueryMap的请求数据体现在URL上,@Field,@FieldMap数据体现在请求体上 但生成的数据是一致的 |
@Path | URL缺省值 |
@URL | URL设置 |
2.请求参数说明
@Header & @Headers
//@Header 添加不固定请求头,作用于方法的参数
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization);
//@Headers 添加请求头,作用于方法
@Headers("Authorization: authorization")
@GET("user")
Call<User> getUser();
@Body
以post方式传递自定义数据类型给服务器
如果提交的是一个Map,作用相当于@Filed,要经过FormBody.Builder类处理成为符合Okhttp格式的表单
FormBody.Builder builder = new FormBody.Builder();
builder.add("key","value");
@Filed & @FiledMap
请求接口
//表示是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
//@Field("username") 表示将String name 的取值作为username的值
@POST("/form")
@FormUrlEncoded
Call<ResponseBody> postCall(@Field("username") String name,@Field("age") int age);
//@FiledMap,map的key作为表单的键
@POST("/form")
@FormUrlEncoded
Call<ResponseBody> postCall(@FieldMap Map<String,Object> map);
使用
Retrofit retrofit = new Retrofit.Builder().baseUrl(URL).addConverterFactory(GsonConverterFactory.create()).build();
GetRequest_Interface anInterface = retrofit.create(GetRequest_Interface.class);
//@Filed
Call<ResponseBody> postCall = anInterface.postCall("eyesee", 14);
//@FiledMap
Map<String,Object> map = new HashMap<>();
map.put("username","eyesee");
map.put("age",14);
Call<ResponseBody> postCall1 = anInterface.postCall(map);
@Part & @PartMap
请求接口
//@Part后面支持三种类型:RequestBody,MultipartBody.Part,任意类型
//除了MultipartBody.Part外,其它类型都必须带上表单字段
//MultipartBody.Part中已经包含了表单字段
//与@Field功能相同,但是携带的参数类型更丰富,适用于文件上传的场景
@POST("/form")
@Multipart
Call<ResponseBody> parCall(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);
//@PartMap
@POST("/form")
@Multipart
Call<ResponseBody> partCall(@PartMap Map<String,RequestBody> args,@Part MultipartBody.Part file);
@POST("/form")
@Multipart
Call<ResponseBody> parCall(@PartMap Map<String,ResponseBody> args);
具体使用
Retrofit retrofit = new Retrofit.Builder().baseUrl(URL).addConverterFactory(GsonConverterFactory.create()).build();
GetRequest_Interface anInterface = retrofit.create(GetRequest_Interface.class);
MediaType textType = MediaType.parse("text/plain");
RequestBody name = RequestBody.create(textType, "eye");
RequestBody age = RequestBody.create(textType, "33");
RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里写文本内容");
//@Part
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
Call<ResponseBody> partCall = anInterface.parCall(name, age, filePart);
//@PartMap
Map<String,RequestBody> fileUpload = new HashMap<>();
fileUpload.put("name",name);
fileUpload.put("age",age);
//这里不会被当成文件,因为没有文件名,文件名包含在Content-Disposition请求头中,但是上面的filePart中有文件名
//fileUpload.put("file",file);
Call<ResponseBody> partMapCall = anInterface.partCall(fileUpload, filePart);
@Query & @QueryMap
//@Query & @QueryMap,用于@GET方法的查询参数(Query=Url中?后面的key-value
// 如url = http://www.println.net/?cate=android,其中,Query = cate
//使用方式同 @Field与@FieldMap
@GET("/")
Call<String> query(@Query("cate") String cate);
@Path
url地址的缺省值
//在使用时,实际url是http://host:post/users/{user}/repos
//{user}是在调用请求接口时传入的参数
@GET("users/{user}/repos")
Call<ResponseBody> getAuthor(@Path("user") String user);
@Url
//使用@Url注解时,@GET传入的URL可以省略
//当GET、POST...HTTP等方法中没有设置Url时,则必须使用@Url提供
@GET
Call<Response> urlCall(@Url String url);
7,关于解析器
数据解析器 | 依赖 |
---|---|
Gson | com.squareup.retrofit2:converter-gson:2.0.2 |
Jackson | com.squareup.retrofit2:converter-jackson:2.0.2 |
Simple XML | com.squareup.retrofit2:converter-simplexml:2.0.2 |
Protobuf | com.squareup.retrofit2:converter-protobuf:2.0.2 |
Moshi | com.squareup.retrofit2:converter-moshi:2.0.2 |
Wire | com.squareup.retrofit2:converter-wire:2.0.2 |
Scalars | com.squareup.retrofit2:converter-scalars:2.0.2 |
8,网络适配器
网络请求适配器 | 依赖 |
---|---|
guava | com.squareup.retrofit2:adapter-guava:2.0.2 |
Java8 | com.squareup.retrofit2:adapter-java8:2.0.2 |
rxjava | com.squareup.retrofit2:adapter-rxjava:2.0.2 |