一、模块划分
聚合工程
顶级模块:new_rpc
父模块:httpclient_rpc
子模块:httpclient_rpc_server、httpclient_rpc_client、httpclient_rpc_pojo
使用顶级模块是因为rpc协议自定义了两种方式,现在介绍的是httpclient_rpc
这种方式
二、pom依赖
1.new_rpc
<groupId>com.zhkucst</groupId>
<artifactId>new_rpc</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>httpclient_rpc</module>
</modules>
2.httpclient_rpc
<parent>
<artifactId>new_rpc</artifactId>
<groupId>com.zhkucst</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>httpclient_rpc</artifactId>
<packaging>pom</packaging>
<modules>
<module>httpclient_rpc_server</module>
<module>httpclient_rpc_client</module>
<module>httpclient_rpc_pojo</module>
</modules>
3.httpclient_rpc_pojo
<parent>
<artifactId>httpclient_rpc</artifactId>
<groupId>com.zhkucst</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>httpclient_rpc_pojo</artifactId>
4.httpclient_rpc_server
<parent>
<artifactId>httpclient_rpc</artifactId>
<groupId>com.zhkucst</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>httpclient_rpc_server</artifactId>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.zhkucst</groupId>
<artifactId>httpclient_rpc_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
5.httpclient_rpc_client
<parent>
<artifactId>httpclient_rpc</artifactId>
<groupId>com.zhkucst</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>httpclient_rpc_client</artifactId>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--httpclient 依赖-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.zhkucst</groupId>
<artifactId>httpclient_rpc_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.1</version>
</dependency>
</dependencies>
三、内容
1.httpclient_rpc_pojo
pojo类
package com.zhkucst.httpclient.pojo;
import sun.security.jca.GetInstance;
import java.io.Serializable;
import java.util.Date;
/**
* @version v1.0
* @ClassName: User
* @Description: TODO
* @Author: fyp
* @data: 2021年 11月 07日 14:55
*/
public class User implements Serializable {
private String name;
private String password;
private Date birth;
public int getAge(){
if(birth == null){
return -1;
}
int birthYear = birth.getYear();
int currentYear = new Date().getYear();
return currentYear - birthYear;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "{\"name\":\""+ name +"\",\"password\":\""+ password +"\"}";
}
}
2.httpclient_rpc_server
服务端控制器,即客户端发起请求的控制区
package com.zhkucst.httpclientserver.controller;
import com.zhkucst.httpclient.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* @version v1.0
* @ClassName: TestController
* @Description: TODO
* @Author: fyp
* @data: 2021年 10月 18日 21:33
*/
@Controller
public class TestController {
/**
* CrossOrigin - 跨域请求注解。在响应头上增加跨域处理允许,可以让ajax跨越请求当前的服务方法
* @param users
* @return
*/
//使用请求体传递请求参数
@RequestMapping(value = "/bodyParams", produces = {"application/json;charset=UTF-8"})
@ResponseBody
@CrossOrigin
public String bodyParams(@RequestBody List<User> users){
System.out.println(users);
return users.toString();
}
@RequestMapping(value = "/params", produces = {"application/json;charset=UTF-8"})
@ResponseBody
public String params(String name, String password){
System.out.println("name - " + name + " ; password - " + password);
return "{\"msg\":\"登录成功\",\"user\":{\"name\":\""+name+"\",\"password\":\""+password+"\"}}";
}
@RequestMapping(value = "/test", produces = {"application/json;charset=UTF-8"})
@ResponseBody
public String test(){
return "{\"msg\":\"处理返回\"}";
}
}
3.httpclient_rpc_client
通过后端实现访问请求,后端以SpringBoot方式启动,前端直接java访问
package com.zhkucst.httpclient;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhkucst.httpclient.pojo.User;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
/**
* @version v1.0
* @ClassName: TestHttpClient
* @Description: TODO
* @Author: fyp
* @data: 2021年 10月 18日 21:46
*/
public class TestHttpClient {
public static void main(String[] args) throws Exception{
//testGetNoParams();
//testGetParams();
testPost();
//testGetParams();
}
/**
* 有参Get请求
* @throws IOException
* @throws URISyntaxException
*/
public static void testGetParams() throws IOException, URISyntaxException {
//基于Builder构建请求地址
HttpClient client = HttpClients.createDefault();
URIBuilder builder = new URIBuilder("http://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("http://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("http://localhost/test");
HttpResponse response = client.execute(post);
System.out.println(EntityUtils.toString(response.getEntity(), "UTF-8"));
//有参数的Post请求
//请求头传递参数,和Get请求携带参数的方式一致
URIBuilder builder = new URIBuilder("http://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("http://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>标签:http,请求,RPC,new,rpc,org,import,手写,httpclient From: https://blog.51cto.com/fyphome/5790973
<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": "http://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>