HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。
使用HttpClient、可以灵活地发送HTTP请求,并且Apache HttpClient提供了很多自定义的请求内容的API(包括连接超时时间设置等)。方便了开发人员测试接口(基于HTTP协议的),既提高了开发效率,也方便了提高代码的健壮性。(后续的RestTemplate的底层也是HttpClient)因此熟悉掌握HttpClient是很重要的必修内容,掌握了HttpClient后,对于HTTP的协议的了解也会更加深刻。
GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE
)。Basic,Digest,NTLMv1,NTLMv2,NTLM2Session,SNPNEGO/Kerberos
认证方案。导入依赖
<dependencies>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
<version>4.5.13version>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpmimeartifactId>
<version>4.5.13version>
dependency>
dependencies>
创建HttpClient
对象(http客户端对象)
CloseableHttpClient client = HttpClientBuilder.create().build();//方式一
CloseableHttpClient client = HttpClients.createDefault();//方式二
两种方式相同,因为方式二的底层就是方式一。
创建请求方法的实例,并指定URL
。因为HttpClient
是实现了所有Http
请求方法,我们只需要创建请求方法实例(Httpxxx),在方法实例中指定URL即可,例如我们要发送Get请求,就创建HttpGet
对象。
如果需要发送带有参数的请求,可调用HttpGet、HttpPost
共同的setParam(HttpParams params)
来添加参数(该方法已经过时/弃用了);HttpGet
推荐使用单独创建uri,构建自己的带参数的get请求的uri。HttpPost
请求则是调用setEntity(HttpEntity entity)
方法来设置请求参数(可以设置对象)。
发送请求则是HttpClient
的工作,调用HttpClient
的execute(HttpUriRequeset request)
发送请求,该方法会返回一个HttpResponse
(响应模板)
调用HttpResponse
的getAllHeader()
、getHeaders(Sring name)
等方法可以获取服务器的响应头,除此之外还可以获取状态码等。通过HttpResponse
的getEntity()
方法可以获取响应的响应实体,该对象包装了服务器的响应内容,程序可以通过该对象获取服务器的响应内容。
最后需要释放资源,关闭HttpClient
和reseponse
的资源连接
GET请求
public class GetClient {
/**
* GET---无参测试
*/
public void doGetTestOne(){
//获得http客户端
CloseableHttpClient client = HttpClientBuilder.create().build();
//创建get请求
HttpGet httpGet = new HttpGet("https://www.cuit.edu.cn/");
//响应模型
CloseableHttpResponse response = null;
try{
//有客户端指定get请求
response = client.execute(httpGet);
//从响应模型中获取响应体
HttpEntity responseEntity = response.getEntity();
System.out.println("响应状态为:"+response.getStatusLine());
if (responseEntity!=null){
System.out.println("响应内容长度为:"+responseEntity.getContentLength());
System.out.println("响应内容为:"+ EntityUtils.toString(responseEntity));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
//释放资源
if(client!=null){
client.close();
}
if (response!=null){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* GET--有参测试
*/
public void doGetTestWayOne(){
//获得http客户端
CloseableHttpClient client = HttpClientBuilder.create().build();
//参数
StringBuilder params = new StringBuilder();
try{
params.append("name=").append(URLEncoder.encode("&","utf-8")).append("&").append("age=24");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//创建Get请求
HttpGet httpGet = new HttpGet("https://www.cuit.edu.cn/?" + params);
//响应模型
CloseableHttpResponse response = null;
try{
//配置信息
RequestConfig config = RequestConfig.custom()
//设置连接超时时间
.setConnectTimeout(5000)
//设置请求超时时间
.setConnectionRequestTimeout(5000)
//socket读写超时时间
.setSocketTimeout(5000)
//设置是否允许重定向(默认为true)
.setRedirectsEnabled(true)
.build();
//将上面的配置信息配入Get请求中
httpGet.setConfig(config);
//由客户端执行Get请求
response = client.execute(httpGet);
//从响应模型中获取响应实体
HttpEntity responseEntity = response.getEntity();
System.out.println("响应状态为:"+response.getStatusLine());
if (responseEntity!=null){
System.out.println("响应内容长度为:"+responseEntity.getContentLength());
System.out.println("响应内容为:"+ EntityUtils.toString(responseEntity,"utf-8"));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(client!=null){
client.close();
}
if (response!=null){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void doGetTestWayTwo(){
CloseableHttpClient client = HttpClientBuilder.create().build();
URI uri = null;
try{
ArrayList<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("name","10"));
params.add(new BasicNameValuePair("age","18"));
//这里设置uri信息,并将参数集合放入uri;
//注: 这里也支持一个键值对一个键值对地往里面方setParameter(String key, String value)
uri = new URIBuilder().setScheme("http").setHost("www.cuit.edu.cn")
// .setPort(12345).setPath("/xw")
.setParameters(params).build();
System.out.println(uri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
//创建httpGet请求
HttpGet httpGet = new HttpGet(uri);
//创建响应模型
CloseableHttpResponse response = null;
try{
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setSocketTimeout(5000)
.setRedirectsEnabled(true).build();
httpGet.setConfig(config);
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
System.out.println("响应状态码:"+response.getStatusLine());
System.out.println("响应内容长度:"+entity.getContentLength());
System.out.println("响应内容:"+EntityUtils.toString(entity,"utf-8"));
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//测试
public static void main(String[] args) {
//new GetClient().doGetTestOne();
//new GetClient().doGetTestWayOne();
new GetClient().doGetTestWayTwo();
}
}
POST请求
public class PostClient {
/**
* POST 无参
*/
public void doPostTestOne(){
//获得http客户端
CloseableHttpClient client = HttpClientBuilder.create().build();
//创建Post请求
HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/index.htm");
//创建响应模型
CloseableHttpResponse response = null;
try{
response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
System.out.println("响应状态码:"+response.getStatusLine());
System.out.println("响应内容长度:"+entity.getContentLength());
System.out.println("响应内容:"+ EntityUtils.toString(entity,"utf-8"));
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
if (client!=null){
client.close();
}
if (response!=null){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* POST 有参
*/
public void doPostTestFour(){
//获的http客户端
CloseableHttpClient client = HttpClientBuilder.create().build();
//参数
StringBuilder params = new StringBuilder();
try{
//字符数据最好encoding; 这样一来, 某些特殊字符才嗯那个传过去(如:某人的名字就是"&",不encoding,传不过去)
params.append("phone=").append(URLEncoder.encode("admin","utf-8"));
params.append("&");
params.append("password=admin");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//创建post请求
HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/?" + params);
//设置ContentType(注:如果只是传入普通参数的话,ContentType不一定非要用application/json)
httpPost.setHeader("Content-Type","application/json;charset=utf-8");
//响应模型
CloseableHttpResponse response = null;
try{
response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
System.out.println("状态码:"+response.getStatusLine());
System.out.println("响应内容长度: "+entity.getContentLength());
System.out.println("响应内容: "+entity);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* POST---有参测试(对象参数)
*/
public void doPostTestTwo(){
//获取Http客户端
CloseableHttpClient client = HttpClientBuilder.create().build();
//创建Post请求
HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/index.htm");
//User user = new User();
//user.setName("潘晓婷");
//user.setAge(18);
//user.setGender("女");
//user.setMotto("姿势要优雅~");
// 我这里利用阿里的fastjson,将Object转换为json字符串;
// (需要导入com.alibaba.fastjson.JSON包)
//String jsonString = JSON.toJSONString(user);
String jsonString = "";
StringEntity stringEntity = new StringEntity(jsonString, "utf-8");
httpPost.setEntity(stringEntity);
httpPost.setHeader("Content-Type", "application/json;charset=utf8");
CloseableHttpResponse response = null;
try{
response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
System.out.println("状态码:"+response.getStatusLine());
System.out.println("响应内容长度:"+entity.getContentLength());
System.out.println("响应内容:"+EntityUtils.toString(entity,"utf-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
if (client!=null){
client.close();
}
if (response!=null){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
//new PostClient().doPostTestOne();
//new PostClient().doPostTestFour();
new PostClient().doPostTestTwo();
}
}
上传文件
public class FileClient {
/**
* 发送文件
注:如果想要灵活方便的传输文件的话,
* 除了引入org.apache.httpcomponents基本的httpclient依赖外
* 再额外引入org.apache.httpcomponents的httpmime依赖。
* 追注:即便不引入httpmime依赖,也是能传输文件的,不过功能不够强大。
*/
public void test4(){
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/file");
CloseableHttpResponse response = null;
try{
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
//第一个文件
String fileKey = "files";
File file1 = new File("D:\\图片\\《Valorant》3440x1440带鱼屏游戏壁纸_彼岸图网.jpg");
/*
防止服务端收到的文件名乱码. 我们这里可以先将文件名URLEncode, 然后服务端拿到文件后URLDecode
文件名其实是放在请求头的Content-Disposition中 如其值form-data; name="files"; filename="头像.jpg"
*/
multipartEntityBuilder.addBinaryBody(fileKey,file1, ContentType.DEFAULT_BINARY, URLEncoder.encode(file1.getName(),"utf-8"));
//其他参数(注:自定义contentType,设置UTF-8是为了防止服务端拿到的参数出现乱码)
ContentType contentType = ContentType.create("text/plain", StandardCharsets.UTF_8);
multipartEntityBuilder.addTextBody("name","等沙利文",contentType);
multipartEntityBuilder.addTextBody("age","25",contentType);
HttpEntity httpEntity = multipartEntityBuilder.build();
httpPost.setEntity(httpEntity);
response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity!=null){
System.out.println("状态码:"+response.getStatusLine());
System.out.println("响应内容长度:"+entity.getContentLength());
System.out.println("响应内容:"+ EntityUtils.toString(entity,"utf-8"));
}
/*
File file1 = new File("D:\\图片\\XXX.jpg");
multipartEntityBuilder.addBinaryBody(fileKey,file1);
*/
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (client!=null){
client.close();
}
if (response!=null){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new FileClient().test4();
}
}
Stream请求
public class StreamClient {
/**
* 发送流
*/
public void test5(){
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("https://www.cuit.edu.cn/index.htm");
CloseableHttpResponse response = null;
try {
ByteArrayInputStream is = new ByteArrayInputStream("流啊流~".getBytes(StandardCharsets.UTF_8));
InputStreamEntity ise = new InputStreamEntity(is);
httpPost.setEntity(ise);
response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
System.out.println("响应状态码:"+response.getStatusLine());
if (entity!=null){
System.out.println("响应内容长度:"+entity.getContentLength());
System.out.println("响应内容:"+ EntityUtils.toString(entity,StandardCharsets.UTF_8));
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (client!=null){
client.close();
}
if (response!=null){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new StreamClient().test5();
}
}