HttPClient简介
在JDK中java.net包下提供了用户HTTP访问的基本功能,但是它缺少灵活性或许多应用所需要的功能。
HttpClient起初是Apache Jakarta Common 的子项目。用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本。2007年成为顶级项目。
通俗解释:HttpClient可以实现使用Java代码完成标准HTTP请求及响应。
代码实现
整体代码架构
- server端是服务端提供远程调用方法
- client是客户端,访问远程方法
- pojo放通用的实体类
Pojo(实体类)
代码结构
user类
package com.shen.pojo;
import java.io.Serializable;
import java.util.Objects;
public class User implements Serializable {
private String username;
private String password;
public User(){
}
public User(String username,String password){
this.username = username;
this.password = password;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return getUsername().equals(user.getUsername()) && getPassword().equals(user.getPassword());
}
@Override
public int hashCode() {
return Objects.hash(getUsername(), getPassword());
}
@Override
public String toString() {
return "{" +
"\"username\":\"" + username + '\"' +
", \"password\":\"" + password + '\"' +
'}';
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
server端(服务端)
代码结构
server端没有修改端口号,使用默认8080端口提供服务
控制器TestController
package com.example.server.controller;
import com.shen.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;
@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 = "/test",produces = {"application/json;charset=UTF-8"})
@ResponseBody
public String test(){
return "{\"msg\":\"返回成功\"}";
}
//有参方法
@RequestMapping(value = "/params",produces = {"application/json;charset=UTF-8"})
@ResponseBody
public String params(String username,String password){
System.out.println("name:"+username+";password:"+password);
return "{\"msg\":\"登录成功\",\"username\":\""+username+"\",\"password\":\""+password+"\"}";
}
}
启动器(ServerApplication)
package com.example.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
导入pojo依赖
<dependency>
<groupId>com.example</groupId>
<artifactId>pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
客户端(client)
代码结构
测试方法(TestHttpClient)
包含有参,无参的get和post请求测试,以及传输实体类的post的请求测试,启动server端后,直接启动main方法即可。
package com.shen.client;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shen.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;
public class TestHttpClient {
public static void main(String[] args) throws IOException, URISyntaxException {
testGetNoParams();
testGetParams();
testPost();
}
/**
* 无参数的get请求
* 使用浏览器,访问网站的过程是
* 1。打开浏览器
* 2,输入地址
* 3。访问
* 4,看结果
* 使用httpclient访问web服务的过程
* 1,创建客户端,相当于打开浏览器
* 2,创建请求地址,相当于输入地址
* 3,发起请求,相当于访问网站
* 4。处理响应结果,相当于浏览器显示结果
*/
public static void testGetNoParams() throws IOException {
//创建客户端对象
HttpClient client = HttpClients.createDefault();
//创建请求地址
HttpGet get = new HttpGet("http://localhost:8080/test");
//发起请求,接收响应对象
HttpResponse response = client.execute(get);
//获取响应体,响应数据是一个基于HTTP协议的标准字符串封装对象
//所以,响应体和响应头,都是封装的http协议数据,直接使用可能有乱码或解码错误
HttpEntity entity = response.getEntity();
//通过HTTP实体工具类,转换响应体数据,使用的字符集是utf-8
String str = EntityUtils.toString(entity,"UTF-8");
System.out.println("服务器返回数据:["+str+"]");
//回收资源
client = null;
}
/**
* 有参方法get
* @throws IOException
*/
public static void testGetParams() throws IOException, URISyntaxException {
HttpClient client = HttpClients.createDefault();
//基于builder构建请求地址
URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/params");
//基于单参数传递,构建请求地址
/*uriBuilder.addParameter("username","shenshen");
uriBuilder.addParameter("password","123456");*/
//基于多参数传递,构建请求地址
List<NameValuePair> list = new ArrayList<>();
list.add(new BasicNameValuePair("username","shenshen1"));
list.add(new NameValuePair() {
@Override
public String getName() {
return "password";
}
@Override
public String getValue() {
return "111111";
}
});
uriBuilder.addParameters(list);
//uri请求构建
URI uri = uriBuilder.build();
HttpResponse response = client.execute(new HttpGet(uri));
String res = EntityUtils.toString(response.getEntity());
System.out.println("params方法返回:"+res);
client = null;
}
/**
* post请求
*/
public static void testPost() throws IOException, URISyntaxException {
HttpClient client = HttpClients.createDefault();
//无参数post请求
HttpPost post = new HttpPost("http://localhost:8080/test");
String res = EntityUtils.toString(client.execute(post).getEntity(),"UTF-8");
System.out.println("post无参请求测试:"+res);
//有参数post请求
//请求头传递参数,和GET请求携带参数的方式一致
URIBuilder uriBuilder = new URIBuilder("http://localhost:8080/params");
uriBuilder.addParameter("username","shen");
uriBuilder.addParameter("password","123456");
URI uri = uriBuilder.build();
HttpResponse response = client.execute(new HttpPost(uri));
System.out.println(EntityUtils.toString(response.getEntity(),"UTF-8"));
//请求体传递参数
HttpPost bodyParamsPost = new HttpPost("http://localhost:8080/bodyParams");
//定义请求协议体,设置请求参数。使用请求体传递参数,需要定义请求体格式,默认是表单
//使用uribuilder构建的uri对象,就是请求体传递参数的
User user = new User("name1","word1");
User user2 = new User("name2","word2");
List<User> users = new ArrayList<>();
users.add(user);
users.add(user2);
//集合users->json
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(users);
//或者拼接一个json格式字符串,表示请求参数,一个List<User>
//这个变量和json变量作用相同
//String paramsString = "[" + user.toString() + "," + user2.toString() + "]";
HttpEntity entity = new StringEntity(json,"application/json","UTF-8");
bodyParamsPost.setEntity(entity);
String responseStr = EntityUtils.toString(client.execute(bodyParamsPost).getEntity(),"UTF-8");
//返回json格式转对象
//1.list里面一个元素转成user对象
String userString = responseStr.substring(1,responseStr.indexOf("},")+1);
User user1 = objectMapper.readValue(userString,User.class);
System.out.println("user1:"+user1);
//2.直接转换list,构建jackson识别的java类型映射
JavaType valueType = objectMapper.getTypeFactory().constructParametricType(List.class,User.class);
List<User> users1 = objectMapper.readValue(responseStr,valueType);
System.out.println("users1:"+users1);
}
}
前端远程调用测试(TestApp)
修改启动端口号为80
package com.shen.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestApp {
public static void main(String[] args) {
SpringApplication.run(TestApp.class,args);
}
}
前端代码编写index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src = "http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
//js中,ajax请求不能跨域
//跨域-ajax所属的站点,和被请求的站点,不是同一个域
//域 -ip,端口,域名,主机名,任何一个有变化,都是不同域
//需要服务器返回,允许跨域
function sendBodyParams(){
$.ajax({
"url":"http://localhost:8080/bodyParams",
"type":"post",
"data":"[{\"username\":\"abc\",\"password\":\"123\"}," +
"{\"username\":\"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>
导入依赖
<!-
- 文章目录
- 繁