1.使用前准备
- 导入依赖
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
implementation 'com.squareup.retrofit2:converter-gson:2.7.0'
2. Retrofit的注解分类
- Retrofit与其他请求框架不同的是,它使用了注解。
- Retrofit的注解分为三大类。分别是HTTP请求方法注解、标记类注解和参数类注解
3. GET请求访问网络
- 创建接收服务器返回数据的类
- 下面的GET请求暂时用不到接收类,我们举了个调用向百度发送请求的案例
package com.example.retrofit;
public class HappyJoke {
private int code;
private String msg;
private Data data;
private Au author;
public Au getAuthor() {
return author;
}
public void setAuthor(Au author) {
author = author;
}
public Data getData() {
return data;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public void setCode(int code) {
this.code = code;
}
public void setData(Data data) {
this.data = data;
}
public void setMsg(String msg) {
this.msg = msg;
}
public class Data{
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
public class Au{
private String name;
private String desc;
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
public void setName(String name) {
this.name = name;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
}
- 编写请求网络接口
- Retrofit提供的请求方法注解有@GET和@POST等,分别代表GET请求和POST请求。
- 这里使用GET请求,访问的地址"https://www.baidu.com/"
- 另外定义了getString方法,返回的是Call类型的参数
package com.example.retrofit;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;
public interface BaiduService {
@GET("/")
Call<ResponseBody> getHomePage();
}
- 接下来创建Retrofit,并创建接口文件
package com.example.retrofit;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//接下来创建Retrofit,并创建接口文件
String url = "https://www.baidu.com/" ;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
BaiduService baiduService = retrofit.create(BaiduService.class);
Call<ResponseBody> call = baiduService.getHomePage();
//用Call请求网络,并处理回调
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
String message = response.body().toString();
Log.d("Ning" , message);
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("Ning" , "onFailure:1111111111");
}
});
}
}
- 这里是异步请求网络,回调的Callback是运行在UI线程的。
- 动态配置URL地址
public interface IpServiceForPath{
@GET("{Path}/getIpInfo.php?ip=59.108.54.37")
Call<IpModel> getIpMsg(@Path("path") String path);
- 在使用的地方
IpServiceForPath ipService = retrofit.create(IpServiceForPath.class);
//传进去参数
Call<IpModel> call = ipService.getIpMsg("service")
- 动态指定查询条件 @Query
- 动态指定查询条件组 @QueryMap
4.POST请求访问网络
- 传输数据类型为键值对:@Field
- FormUrlEncoded表示这是一个表单请求
- 在getIpMsg方法中使用@Field注解来标注对应的String类型数据的键,从而组成一组键值对进行传递。
package com.example.retrofit;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface IpServiceForPost {
@FormUrlEncoded
@POST("getIpInfo.php")
Call<IpModel> getIpMsg(@Field("ip") String first);
}
2. 传输数据类型为JSON字符串:@Body
- 我们也可以用POST请求将JSON字符串作为请求体发送到服务器
public interface IpServiceForPost {
@POST("getIpInfo.php")
Call<IpModel> getIpMsg(@Body IP ip);
}
package com.example.retrofit;
public class IP {
private String ip;
public IP(String ip) {
this.ip = ip;
}
}
- 发送网络请求的代码都一样
...
IpServiceForPostBody ipService = retrofit.create(IpServiceForPostBody.class);
Call<IpModel> call = ipService.getIpMsg(new IP(ip));
...
3. 单个文件上传:@Part
- Multipart注解表示允许多个@Part
- updateUser方法的第一个参数是准备上传的图片文件,使用了MultipartBody.Part
- 第二个参数是RequestBody类型的,它用来传递简单的键值对
public interface UpLoadFileForPart {
@Multipart
@POST("user/photo")
Call<User> updateUser(@Part MultipartBody.Part photo , @Part("description")RequestBody description);
}
...
File file = new File(Environment.getExternalStorageDirectory() , "Ning.png");
RequestBody photoRequestBody = RequestBody.create(MediaType.parse("image.png") ,file);
MultipartBody.Part photo = MultipartBody.Part.createFormData("photos" ,"Ning.png" , photoRequestBody);
UpLoadFileForPart upLoadFileForPart = retrofit.create(UpLoadFileForPart.class);
Call<User> call1 = upLoadFileForPart.updateUser(photo , RequestBody.create(null , "Ning"));
...
- 多个文件上传
- 和单个上传文件类似,只不过用Map封装了上传的文件
5. 消息报头(Header)
- 在HTTP请求中,为了过滤掉不安全的访问、添加特殊加密的访问或者防止被攻击等,以便减轻服务器的压力和保证请求的安全,通常会在消息报头中携带一些特殊的消息头处理。
- Retrofit提供了@Header来添加消息报头。添加消息报头有静态和动态两种方式
- 静态
public interface SomeService {
@GET("some/endpoint")
@Headers("Accept-Encoding: application/json")
Call<ResponseBody> getCarType();
}
- 使用Headers注解来添加消息报头
- 如果想要添加多个消息报头,则可以使用{}包起来
public interface SomeService {
@GET("some/endpoint")
@Headers({
"Accept-Encoding: application/json"
"User-Agent: MoonRetrofit"
})
Call<ResponseBody> getCarType();
}
- 动态
- 使用@Header注解,通过getCarType方法来动态添加。外界传参进来
public interface SomeService {
@GET("some/endpoint")
Call<ResponseBody> getCarType(@Header("Location") String location);
}