RPC之HttpClient与OkHttp3的实现
概念
在进行HttpClient和OkHttp的学习之前,我们得先了解下RPC这个概念。所谓的RPC,英文全称为Remote Procedure Call,翻译成中文的意思是远程过程调用,它是一种通过网络从远程计算机程序上请求服务获取数据的一种协议。说的更直白点就是要实现不同服务器之间的服务调用。而随着分布式系统的普及,RPC在现在的系统开发中起着非常重用的作用。
此次我们将要学习的HttpClient和OkHttp都可以实现RPC远程服务调用。HttpClient是Apache Jakarta Common 下的子项目。它是一种基于HTTP协议的客户端编程工具包,而OkHttp是一种适用于Android和Java应用程序的HTTP客户端。从概念上来看,两者都是基于HTTP协议的客户端程序,也都能实现远程服务请求的调用,所以接下来,我们通过案例对HttpClient与OkHttp3做一个详细的学习。
服务端
需求分析
在正式学习HttpClient和OkHttp之前,我们需要先搭建服务器对外提供服务,业务非常简单:
1.实现用户列表的查询
2.实现根据用户ID查询用户详情信息
3.实现用户的新增
为了方便环境的构建,此次我采用SprongBoot对项目进行构建,当然你也可以选中你自己比较熟悉的技术来搭建环境,完成上述需求的开发工作。那接下来我们就把整个环境搭建的步骤来实现下。
环境搭建
1.创建springboot项目
2.pom.xml导入对应的依赖jar包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
3.编写引导类
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class,args);
}
}
4.编写模型类
public class User {
private Integer id;
private String name;
private String password;
//构造函数和setter、getter方法略
}
5.编写Controller类
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 查询所有用户
* @return
*/
@GetMapping("/findAll")
public List<User> findAll(){
return userService.findAll();
}
@GetMapping("/findUserById/{id}")
public User findUserById(@PathVariable("id") Integer id){
return userService.findUserById(id);
}
@PostMapping("/addUserByJson")
public Map<String,Object> addUserByJson(@RequestBody User user){
Map<String,Object> rst = new HashMap<String,Object>();
try{
userService.addUser(user);
rst.put("success",true);
}catch(Exception e){
e.printStackTrace();
rst.put("success",false);
rst.put("message","添加用户失败");
}
return rst;
}
@PostMapping("/addUser")
public Map<String,Object> addUser(User user){
Map<String,Object> rst = new HashMap<String,Object>();
try{
userService.addUser(user);
rst.put("success",true);
}catch(Exception e){
e.printStackTrace();
rst.put("success",false);
rst.put("message","添加用户失败");
}
return rst;
}
}
7.编写service接口类
public interface UserService {
/**
* 查询用户列表
* @return
*/
public List<User> findAll();
/**
* 根据ID查询用户信息
* @param id
* @return
*/
public User findUserById(Integer id);
/**
* 新增用户
* @param user
*/
public void addUser(User user);
}
8.编写service实现类
@Service
public class UserServiceImpl implements UserService {
private static final Map<Integer,User> MAP = new HashMap<Integer,User>();
static{
MAP.put(1,new User(1,"张三丰","zsf"));
MAP.put(2,new User(2,"赵敏","zm"));
MAP.put(3,new User(3,"周芷若","zzr"));
MAP.put(4,new User(4,"小昭","xz"));
MAP.put(5,new User(5,"张无忌","zwj"));
MAP.put(6,new User(6,"金毛狮王","jmsw"));
MAP.put(7,new User(7,"张翠山","zcs"));
MAP.put(8,new User(8,"殷素素","yss"));
}
@Override
public List<User> findAll() {
List<User> users = new ArrayList<User>();
for (Integer id : MAP.keySet()) {
users.add(MAP.get(id));
}
return users;
}
@Override
public User findUserById(Integer id) {
User user = MAP.get(id);
return user;
}
@Override
public void addUser(User user) {
System.out.println("新增用户成功,用户的信息为"+user.toString());
}
}
功能测试
可以借助于浏览器或者postMan等工具进行测试,此处不是我们研究的重点,所以该处需要自行测试通过即可。
经过测试我们可以获取一下URL地址
查询用户列表: GET http://loalhost:8080/user/findAll
根据用户ID查询用户详情: GET http://localhost:8080/user/findUserById/具体的ID值
新增用户: POST http://localhost:8080/user/addUserByJson 发送json数据
POST http://localhost:8080/user/addUser 发送form表单数据
客户端(HttpClient)
1.导入对应的jar包
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.30</version>
</dependency>
</dependencies>
2.通过HttpClient发送GET请求查询所有用户列表
@Test
public void testFindAll() throws Exception{
//创建HttpClient对象
HttpClient httpClient = HttpClients.createDefault();
//创建GET请求对象
HttpGet httpGet = new HttpGet("http://localhost:8080/user/findAll");
//发送请求获取结果
HttpResponse response = httpClient.execute(httpGet);
//解析结果
String rst = EntityUtils.toString(response.getEntity());
System.out.println(rst);
}
运行查询结果为:
3.通过HttpClient发送GET请求查询指定用户的详细信息
@Test
public void testFindById() throws Exception{
//创建HttpClient对象
HttpClient httpClient = HttpClients.createDefault();
//创建GET请求对象
HttpGet httpGet = new HttpGet("http://localhost:8080/user/findUserById/1");
//发送请求获取结果
HttpResponse response = httpClient.execute(httpGet);
//解析结果
String rst = EntityUtils.toString(response.getEntity());
System.out.println(rst);
}
运行查询结果为:
4.通过HttpClient发送POST请求完成用户的新增功能,发送数据类型为Form表单数据类型
@Test
public void testAddUserByForm() throws Exception{
//创建HttpClient对象
HttpClient httpClient = HttpClients.createDefault();
//创建POST请求对象
HttpPost httpPost = new HttpPost("http://localhost:8080/user/addUser");
//封装发送数据
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name","唐僧"));
params.add(new BasicNameValuePair("password","ts"));
HttpEntity entity = new UrlEncodedFormEntity(params,"utf-8");
httpPost.setEntity(entity);
//发送请求获取结果
HttpResponse response = httpClient.execute(httpPost);
//解析结果
String rst = EntityUtils.toString(response.getEntity());
System.out.println(rst);
}
运行查询结果为:
服务端
客户端
5.通过HttpClient发送POST请求完成用户的新增功能,发送数据类型为JSON数据类型
@Test
public void testAddUserByJSON()throws Exception{
//创建HttpClient对象
HttpClient httpClient = HttpClients.createDefault();
//创建POST请求对象
HttpPost httpPost = new HttpPost("http://localhost:8080/user/addUserByJson");
//封装发送数据
Map<String,Object> paramMap = new HashMap<String,Object>();
paramMap.put("name","孙悟空");
paramMap.put("password","swk");
String jsonString = JSONObject.toJSONString(paramMap);
StringEntity entity = new StringEntity(jsonString,"utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
//发送请求获取结果
HttpResponse response = httpClient.execute(httpPost);
//解析结果
String rst = EntityUtils.toString(response.getEntity());
System.out.println(rst);
}
运行查询结果为:
服务端
客户端
客户端(OkHttp3)
1.导入对应的jar包
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.9.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.30</version>
</dependency>
</dependencies>
2.通过HttpClient发送GET请求查询所有用户列表
@Test
public void testFindAll() throws Exception{
//创建OkHttpClient对象
OkHttpClient httpClient = new OkHttpClient();
//构建请求request对象
Request request = new Request.Builder()
.url("http://localhost:8080/user/findAll").build();
//发送请求
Response response = httpClient.newCall(request).execute();
//解析结果
String rst = response.body().string();
System.out.println(rst);
}
运行查询结果为:
3.通过HttpClient发送GET请求查询指定用户的详细信息
@Test
public void testFindAll() throws Exception{
//创建OkHttpClient对象
OkHttpClient httpClient = new OkHttpClient();
//构建请求request对象
Request request = new Request.Builder()
.url("http://localhost:8080/user/findUserById/3").build();
//发送请求
Response response = httpClient.newCall(request).execute();
//解析结果
String rst = response.body().string();
System.out.println(rst);
}
运行查询结果为:
4.通过HttpClient发送POST请求完成用户的新增功能,发送数据类型为Form表单数据类型
@Test
public void testAddUserByForm() throws Exception{
//创建OkHttpClient对象
OkHttpClient httpClient = new OkHttpClient();
//构建请求参数
RequestBody requestBody = new FormBody.Builder()
.add("name","猪八戒")
.add("password","zbj").build();
//构建请求request对象
Request request = new Request.Builder()
.url("http://localhost:8080/user/addUser").post(requestBody).build();
//发送请求
Response response = httpClient.newCall(request).execute();
//解析结果
String rst = response.body().string();
System.out.println(rst);
}
运行查询结果为:
服务端
客户端
5.通过HttpClient发送POST请求完成用户的新增功能,发送数据类型为JSON数据类型
@Test
public void testAddUserByJSON()throws Exception{
//创建OkHttpClient对象
OkHttpClient httpClient = new OkHttpClient();
//构建请求参数
Map<String,Object> paramMap = new HashMap<String,Object>();
paramMap.put("name","沙僧");
paramMap.put("password","ss");
String jsonString = JSONObject.toJSONString(paramMap);
RequestBody requestBody = FormBody
.create(MediaType.parse("application/json;charset=utf-8"),jsonString);
//构建请求request对象
Request request = new Request.Builder()
.url("http://localhost:8080/user/addUserByJson").post(requestBody).build();
//发送请求
Response response = httpClient.newCall(request).execute();
//解析结果
String rst = response.body().string();
System.out.println(rst);
}
运行查询结果为:
服务端
客户端
总结
通过上述HttpClient和OkHttp3完成从服务器端获取数据的方式,我们已经完成了通过网络的方式来获取其
用户管理模块服务器上的内容。在上述程序的基础上,大家也可以完成更加复杂的功能模块。