如何实现手写支持HTTP协议的远程过程调用(RPC)框架?

2026-05-27 22:261阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1135个文字,预计阅读时间需要5分钟。

如何实现手写支持HTTP协议的远程过程调用(RPC)框架?

一、模块划分 + 聚合工程 + 顶级模块:new_rpc

二、父模块:httpclient_rpc

三、子模块:httpclient_rpc_server、httpclient_rpc_client、httpclient_rpc_pojo

四、使用顶级模块的原因:因为rpc协议自定义

一、模块划分

聚合工程

顶级模块:​new_rpc​​

父模块:​localhost/params");
//基于单参数传递,构建请求地址
//builder.addParameter("name", "bjsxt");
//builder.addParameter("password", "admin123");
//URI uri = builder.build();


//基于多参数传递,构建请求地址
List<NameValuePair> nvps = new ArrayList<>();
nvps.add(new BasicNameValuePair("name", "bjsxt"));
nvps.add(new BasicNameValuePair("password", "admin123"));
builder.addParameters(nvps);
URI uri = builder.build();


String result = EntityUtils.toString(client.execute(new HttpGet(uri)).getEntity());
System.out.println(result);


}


/**
* 无参数GET请求
* 使用浏览器,访问网站的过程是:
* 1、打开浏览器
* 2、输入网址
* 3、访问
* 4、看结果
* 使用HttpClient,访问WEB服务的过程:
* 1、创建客户端,相当于打开浏览器
* 2、创建请求地址,相当于输入地址
* 3、发起请求,相当于访问网站(回车键)
* 4、处理响应结果,相当于浏览器显示结果
*/
private static void testGetNoParams() throws IOException {
// 创建客户端对象
HttpClient client = HttpClients.createDefault();
// 创建请求地址
HttpGet get = new HttpGet("localhost:80/test");
// 发起请求,接收响应对象
HttpResponse response = client.execute(get);
// 获取响应体,响应数据是一个基于HTTP协议标准字符串封装的对象
HttpEntity entity = response.getEntity();
// 通过HTT实体工具类,转换响应体数据,使用的字符串是UTF-8
String responseString = EntityUtils.toString(entity, "UTF-8");


System.out.println("服务器响应的数据是 - [ " + responseString + "]");


client = null;
}


/**
* POST请求
*/
public static void testPost() throws Exception {
//无参数Post请求
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("localhost/test");
HttpResponse response = client.execute(post);
System.out.println(EntityUtils.toString(response.getEntity(), "UTF-8"));


//有参数的Post请求
//请求头传递参数,和Get请求携带参数的方式一致
URIBuilder builder = new URIBuilder("localhost/params");
builder.addParameter("name", "post");
builder.addParameter("password", "postPassword");
URI uri = builder.build();
HttpResponse postResponse = client.execute(new HttpPost(uri));
System.out.println(EntityUtils.toString(postResponse.getEntity(), "UTF-8"));


//请求体传递参数
HttpPost bodyParamsPost = new HttpPost("localhost/bodyParams");
//定义请求体协议,设置请求参数。使用请求体传递参数的时候,需要定义请求体格式。默认是表单格式
//使用URLBuilder构建的URI对象,就是请求体传递参数的。
User u1 = new User();
u1.setName("zs");
u1.setPassword("123");
User u2 = new User();
u2.setName("ls");
u2.setPassword("456");


//手动json格式化
//String paramsString = "[" + u1.toString() + "," + u2.toString() + "]";


//使用jackson框架格式化
List<User> list = new ArrayList<>();
list.add(u1);
list.add(u2);
String paramsString;
ObjectMapper om = new ObjectMapper();
paramsString = om.writeValueAsString(list);


HttpEntity entity = new StringEntity(paramsString, "application/json", "UTF-8");
bodyParamsPost.setEntity(entity);
System.out.println(EntityUtils.toString(client.execute(bodyParamsPost).getEntity(), "UTF-8"));
String responseString = EntityUtils.toString(client.execute(bodyParamsPost).getEntity(), "UTF-8");
//将一个json格式的对象转换为java对象
String userString = responseString.substring(1, responseString.indexOf("},") + 1);
User responseUser = om.readValue(userString, User.class);
System.out.println(responseUser);
//将以json格式的对象数组转换为java对象数组
JavaType valueType = om.getTypeFactory().constructParametricType(List.class, User.class);
List<User> responseUserList = om.readValue(responseString, valueType);
System.out.println(responseUserList);


}

}

通过页面的​​ajax​​​请求访问,后端以​​springboot​​启动,前端以​web​​​启动

注意需要导入​​jquery.js​​包才可使用ajax请求,这里如果使用了跨域请求,也就是前后端分离请求,就需要在后端设置​​@CrossOrigin​​来允许跨域访问

后端没有设置​​@CrossOrigin​​会导致跨域请求而访问失败

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="jquery-3.5.1.min.js"></script>
<script type="text/javascript">
//javascript中默认的,ajax请求不能跨域
//跨域 - ajax所属的站点,和被请求的站点,不是同一个域
//域 - id,端口,域名,主机名,任何一个有变化,都是不同域
function sendBodyParams(){
$.ajax({
"url": "localhost:80/bodyParams",
"type": "post",
"data": "[{\"name\":\"abc\",\"password\":\"123\"},{\"name\":\"def\",\"password\":\"456\"}]",
"contentType": "application/json",//必须设定,代表请求体的格式。默认是text/plain,默认是参数名=参数值&参数名=参数值
"dataType": "json",
"success": function(data){
alert(data);
console.log(data);
}
});
}
</script>
</head>
<body style="text-align: center">
<button onclick="sendBodyParams()">测试ajax请求,请求体传递JSON数据</button>
</body>
</html>

如何实现手写支持HTTP协议的远程过程调用(RPC)框架?

本文共计1135个文字,预计阅读时间需要5分钟。

如何实现手写支持HTTP协议的远程过程调用(RPC)框架?

一、模块划分 + 聚合工程 + 顶级模块:new_rpc

二、父模块:httpclient_rpc

三、子模块:httpclient_rpc_server、httpclient_rpc_client、httpclient_rpc_pojo

四、使用顶级模块的原因:因为rpc协议自定义

一、模块划分

聚合工程

顶级模块:​new_rpc​​

父模块:​localhost/params");
//基于单参数传递,构建请求地址
//builder.addParameter("name", "bjsxt");
//builder.addParameter("password", "admin123");
//URI uri = builder.build();


//基于多参数传递,构建请求地址
List<NameValuePair> nvps = new ArrayList<>();
nvps.add(new BasicNameValuePair("name", "bjsxt"));
nvps.add(new BasicNameValuePair("password", "admin123"));
builder.addParameters(nvps);
URI uri = builder.build();


String result = EntityUtils.toString(client.execute(new HttpGet(uri)).getEntity());
System.out.println(result);


}


/**
* 无参数GET请求
* 使用浏览器,访问网站的过程是:
* 1、打开浏览器
* 2、输入网址
* 3、访问
* 4、看结果
* 使用HttpClient,访问WEB服务的过程:
* 1、创建客户端,相当于打开浏览器
* 2、创建请求地址,相当于输入地址
* 3、发起请求,相当于访问网站(回车键)
* 4、处理响应结果,相当于浏览器显示结果
*/
private static void testGetNoParams() throws IOException {
// 创建客户端对象
HttpClient client = HttpClients.createDefault();
// 创建请求地址
HttpGet get = new HttpGet("localhost:80/test");
// 发起请求,接收响应对象
HttpResponse response = client.execute(get);
// 获取响应体,响应数据是一个基于HTTP协议标准字符串封装的对象
HttpEntity entity = response.getEntity();
// 通过HTT实体工具类,转换响应体数据,使用的字符串是UTF-8
String responseString = EntityUtils.toString(entity, "UTF-8");


System.out.println("服务器响应的数据是 - [ " + responseString + "]");


client = null;
}


/**
* POST请求
*/
public static void testPost() throws Exception {
//无参数Post请求
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("localhost/test");
HttpResponse response = client.execute(post);
System.out.println(EntityUtils.toString(response.getEntity(), "UTF-8"));


//有参数的Post请求
//请求头传递参数,和Get请求携带参数的方式一致
URIBuilder builder = new URIBuilder("localhost/params");
builder.addParameter("name", "post");
builder.addParameter("password", "postPassword");
URI uri = builder.build();
HttpResponse postResponse = client.execute(new HttpPost(uri));
System.out.println(EntityUtils.toString(postResponse.getEntity(), "UTF-8"));


//请求体传递参数
HttpPost bodyParamsPost = new HttpPost("localhost/bodyParams");
//定义请求体协议,设置请求参数。使用请求体传递参数的时候,需要定义请求体格式。默认是表单格式
//使用URLBuilder构建的URI对象,就是请求体传递参数的。
User u1 = new User();
u1.setName("zs");
u1.setPassword("123");
User u2 = new User();
u2.setName("ls");
u2.setPassword("456");


//手动json格式化
//String paramsString = "[" + u1.toString() + "," + u2.toString() + "]";


//使用jackson框架格式化
List<User> list = new ArrayList<>();
list.add(u1);
list.add(u2);
String paramsString;
ObjectMapper om = new ObjectMapper();
paramsString = om.writeValueAsString(list);


HttpEntity entity = new StringEntity(paramsString, "application/json", "UTF-8");
bodyParamsPost.setEntity(entity);
System.out.println(EntityUtils.toString(client.execute(bodyParamsPost).getEntity(), "UTF-8"));
String responseString = EntityUtils.toString(client.execute(bodyParamsPost).getEntity(), "UTF-8");
//将一个json格式的对象转换为java对象
String userString = responseString.substring(1, responseString.indexOf("},") + 1);
User responseUser = om.readValue(userString, User.class);
System.out.println(responseUser);
//将以json格式的对象数组转换为java对象数组
JavaType valueType = om.getTypeFactory().constructParametricType(List.class, User.class);
List<User> responseUserList = om.readValue(responseString, valueType);
System.out.println(responseUserList);


}

}

通过页面的​​ajax​​​请求访问,后端以​​springboot​​启动,前端以​web​​​启动

注意需要导入​​jquery.js​​包才可使用ajax请求,这里如果使用了跨域请求,也就是前后端分离请求,就需要在后端设置​​@CrossOrigin​​来允许跨域访问

后端没有设置​​@CrossOrigin​​会导致跨域请求而访问失败

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="jquery-3.5.1.min.js"></script>
<script type="text/javascript">
//javascript中默认的,ajax请求不能跨域
//跨域 - ajax所属的站点,和被请求的站点,不是同一个域
//域 - id,端口,域名,主机名,任何一个有变化,都是不同域
function sendBodyParams(){
$.ajax({
"url": "localhost:80/bodyParams",
"type": "post",
"data": "[{\"name\":\"abc\",\"password\":\"123\"},{\"name\":\"def\",\"password\":\"456\"}]",
"contentType": "application/json",//必须设定,代表请求体的格式。默认是text/plain,默认是参数名=参数值&参数名=参数值
"dataType": "json",
"success": function(data){
alert(data);
console.log(data);
}
});
}
</script>
</head>
<body style="text-align: center">
<button onclick="sendBodyParams()">测试ajax请求,请求体传递JSON数据</button>
</body>
</html>

如何实现手写支持HTTP协议的远程过程调用(RPC)框架?