本文出自门心叼龙的博客,属于原创类容,未经允许,不得转载。
本专栏的同步视频教程已经发布到CSDN学院:https://edu.csdn.net/course/detail/30408
调用更加方便,更加安全,架构清晰,代码简洁,反对臃肿,这是一个好软件永远所追求的目标,今天我们就通过Retrofit来感受一下他的魅力,看看和直接使用OkHttp进行调用到底方便在哪里?注意了:本专栏是基于Retrofit 2.9.6的研究。
在上一篇文章我们主要介绍了Retrofit的一个概况,以及几个常用的Android网络框架他们之间的区别,今天我们就来体验一下Retrofit的使用,我们还是以okhttp专栏中的两个接口为例进行演示,一个用户登录的get请求和一个用户注册的post请求。
实体定义
- User的定义:
public class User {
private String username;// string 用户名
private int password;// string 密码
}
- BaseeResponse的定义
public class BaseResponse {
private int code;// Int 响应码
private String msg;// String 响应消息
}
- AddUserResponse的定义
public class AddUserResponse extends BaseResponse {
private User user;
}
服务端定义
服务端使用SpringBoot实现,下面我们看服务端是怎么定义的:
- Controller的定义
@RestController
@RequestMapping("/user")
public class UserController {
Logger logger = LoggerFactory.getLogger(UserController.class);
...
...
}
- loginGet方法:
//1.用户登录的get请求
@GetMapping("/login/get")
public BaseResponse loginGet(@RequestParam String username, @RequestParam int password) {
logger.info("login start...");
BaseResponse response = new BaseResponse();
if ("mxdl".equals(username) && password == 123456) {
response.setCode(0);
response.setMsg("登录成功");
} else {
response.setCode(-1);
response.setMsg("登录失败");
}
return response;
}
- addUserPost方法:
//2.用户注册的post请求
@PostMapping("/addUser/post")
public AddUserResponse addUserPost(@RequestBody User user) {
logger.info("login start...");
AddUserResponse response = new AddUserResponse();
if (user != null) {
response.setCode(0);
response.setMsg("创建成功");
response.setUser(user);
} else {
response.setCode(-1);
response.setMsg("创建失败");
}
return response;
}
客户端实现
服务端和客户端是一 一对应的,下面我们看客户端使用Retrofit是怎么实现的:
- 定义服务接口
public interface UserService {
@GET("user/login/get")
Call<BaseResponse> loginGet(@Query("username") String username, @Query("password") String password);
@POST("user/addUser/post")
Call<AddUserResponse> addUserPost(@Body User user);
}
定义了一个用户服务UserService,它是一个接口,接口里面定义个两个方法,一个用户登录的loginGet方法,和一个用户注册的addUserPost方法,通过注解完成了对请求数据的封装,调用网络请求就像调用普通方法一样的简单,方便,各个注解的主要意义如下:
- loginGet方法:
注解 | 类型 | 作用 |
---|---|---|
@GET | 方法注解 | 1.注解的名称指定该方法是一个get方法 2.注解的值指定请求的url地址 |
@QUERY | 参数注解 | 1.注解名称指定这是url后缀参数 2.注解的值指定后缀参数的名称 |
- addUserPost方法:
注解 | 注解 | 作用 |
---|---|---|
@POST | 方法注解 | 1.注解名称指定该方法是一个post方法 2.注解的值指定该请求的url地址 |
@Body | 参数注解 | 1.注解名称指定请求是一个json串格式的请求体 |
通过代码我们不难发现,服务端和客户端一样也是restful风格的,他们的参数对应关系如下:
客户端和服务端对比
客户端 | 服务端 |
---|---|
@GET(“user/login”) | @GetMapping("/login") |
@POST(“user/addUser”) | @PostMapping("/addUser") |
@Query(“username”) String username | @RequestParam String username |
@Query(“password”) String password | @RequestParam int password |
@Body User user | @RequestBody User user |
服务端和客户端的都定义好了,下面我们看它是怎么使用的:
使用用户登录方法
- 用户登录
public void loginGet(View view) {
Log.v("MYTAG","loginGet start...");
//1.利用建造者模式创建一个Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.0.189:8080")
.addConverterFactory(GsonConverterFactory.create())
.build();
//2.通过动态代理创建一个用户服务
UserService userService = retrofit.create(UserService.class);
//3.创建一个登录命令
Call<BaseResponse> loginCall = userService.loginGet("mxdl", "123456");
//4.执行登录命令
loginCall.enqueue(new Callback<BaseResponse>() {
@Override
public void onResponse(Call<BaseResponse> call, Response<BaseResponse> response) {
Log.v("MYTAG", "onResponse start...");
Log.v("MYTAG", response.body().toString());
}
@Override
public void onFailure(Call<BaseResponse> call, Throwable t) {
Log.v("MYTAG", "onFail start...");
Log.v("MYTAG", t.toString());
}
});
}
- 利用建造者模式创建一个Retrofit
- 通过动态代理创建一个用户服务
- 创建一个登录命令
- 执行登录命令
使用用户注册方法
- 用户注册
public void addUserPost(View view) {
Log.v("MYTAG", "addUserPost start...");
//1.利用建造者模式创建一个Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.0.189:8080")
.addConverterFactory(GsonConverterFactory.create())
.build();
//2.创建一个用户服务
UserService userService = retrofit.create(UserService.class);
//3.创建一个添加用户的命令
Call<AddUserResponse> addUserCAll = userService.addUserPost(new User("mxdl", 123456));
//4.执行一个命令
addUserCAll.enqueue(new Callback<AddUserResponse>() {
@Override
public void onResponse(Call<AddUserResponse> call, Response<AddUserResponse> response) {
Log.v("MYTAG", "onResponse start...");
Log.v("MYTAG", response.body().toString());
}
@Override
public void onFailure(Call<AddUserResponse> call, Throwable t) {
Log.v("MYTAG", "onFail start...");
Log.v("MYTAG", t.toString());
}
});
}
- 利用建造者模式创建一个Retrofit
- 创建一个用户服务
- 创建一个添加用户的命令
- 执行一个命令
测试验证
- loginGet方法
2020-07-19 12:26:13.552 6567-6567/com.mxdl.retrofit2 V/MYTAG: loginGet start...
2020-07-19 12:26:13.553 6567-6567/com.mxdl.retrofit2 V/MYTAG: hasJava8Types:true
2020-07-19 12:26:13.634 6567-6567/com.mxdl.retrofit2 V/MYTAG: create start...
2020-07-19 12:26:13.634 6567-6567/com.mxdl.retrofit2 V/MYTAG: Proxy invoke start...
2020-07-19 12:26:13.634 6567-6567/com.mxdl.retrofit2 V/MYTAG: loadServiceMethod start...
2020-07-19 12:26:14.352 6567-6567/com.mxdl.retrofit2 V/MYTAG: onResponse start...
2020-07-19 12:26:14.352 6567-6567/com.mxdl.retrofit2 V/MYTAG: BaseResponse{code=0, msg='登录成功'}
- addUserPost方法
2020-07-19 12:27:55.588 6567-6567/com.mxdl.retrofit2 V/MYTAG: addUserPost start...
2020-07-19 12:27:55.589 6567-6567/com.mxdl.retrofit2 V/MYTAG: create start...
2020-07-19 12:27:55.590 6567-6567/com.mxdl.retrofit2 V/MYTAG: Proxy invoke start...
2020-07-19 12:27:55.590 6567-6567/com.mxdl.retrofit2 V/MYTAG: loadServiceMethod start...
2020-07-19 12:27:55.738 6567-6567/com.mxdl.retrofit2 V/MYTAG: onResponse start...
2020-07-19 12:27:55.738 6567-6567/com.mxdl.retrofit2 V/MYTAG: AddUserResponse{user=User{username='mxdl', password=123456}}
通过日志我们清楚的看到loginGet方法和addUserPost都能正常返回。
小结
今天我们就分享到这里,我们通过SpringBoot搭建了一个服务端,客户端定义了一个接口服务,接口里面通过注解定义了两个网络请求的方法,Retrofit能把接口方法适配成OkHttp中请求命令Call,有了这个请求命名我们就可以发起一个网络请求了,我们会发现在OkHttp中调用用户登录的时候需要通过HttpUrl来构建一个Request,在用户注册的时候会通过RequestBody来构建一个Request,而这些操作在Retrofit中都不需要了,我们只需要简简单单的通过注解来定义方法就可以了,我们就可以像调普通方法一样的调用网络请求了,我们有没有感觉到通过Retrofit来发起一个网络请求更加方便了,代码的可读性更强了,比起复杂HttpClient而言,我们会不会大声的喊一声:“Retrofit,I LOVE YOU”,哈哈哈,下一篇文章我们将介绍Retrofit更多注解的高级用法。
最后我将本文的相关源码上传到了github上: