HttpClient Java客户端
文章目录
- HttpClient Java客户端
- 建立使用HttpClient的环境
- HttpGet请求
- HttpGet带参请求
- HttpPost请求
- HttpPost带参请求(提交表单数据)
- HttpClient连接池+请求配置
HttpClient Java客户端
HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
HttpClient主要功能:
- 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
- 支持自动转向
- 支持 HTTPS 协议
支持代理服务器等
(以上资料来自百度百科)
建立使用HttpClient的环境
如果创建的是maven项目的话可以导入依赖:
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
如果创建的是JavaWeb项目的话可以直接引入Jar包:httpclient-4.5.2.jar
。
想要其他版本的HttpClient工具的话可以搜索maven HttpClient
下载。
这样就可以使用HttpClient来请求浏览器了。
HttpClient请求的步骤大致分为几步(类似人操作浏览器的步骤):
- 创建HttpClient的连接(打开浏览器建立与浏览器的连接)
- 创建请求,输入URI地址向浏览器发起请求(手动输入URI地址)
- HttpClient请求URI地址(浏览器中按回车发起请求)
- 拿到response响应数据(浏览器接收数据,解析渲染到页面)
以上就完成了从请求到接收数据的一个过程。下面看一下简单实现。
HttpGet请求
以GET请求的方式向百度贴吧发送一个请求:
//HttpClient发送GET请求
public class HttpGetRequest {
public static void main(String[] args) {
//百度贴吧的uri地址
String uri = "https://tieba.baidu.com/index.html";
//1、创建HttpClient连接
CloseableHttpClient httpClient = HttpClients.createDefault();
//2、创建HtpGet请求
HttpGet httpGet = new HttpGet(uri);
//3、HttpClient发送请求
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
//4、拿到请求页面的返回数据,请求成功才有数据啊!
HttpEntity entity = null;
if (response != null && response.getStatusLine().getStatusCode() == 200) {
//获取服务器返回的实体数据
entity = response.getEntity();
//把实体数据转换成指定类型的字符串
String context = EntityUtils.toString(entity, "utf-8");
System.out.println(context);
}
} catch (IOException e) {
e.printStackTrace();
//发送请求异常
} finally {
//不管如何关闭响应、请求的连接
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
返回数据的部分截图:
HttpGet带参请求
在返回的这部分数据中找到一个请求地址发送一个带参数的GET请求,就以请求乘风破浪的姐姐
为例:
//HttpClient发送带参数的GET请求
public class HttpGetRequestParam {
public static void main(String[] args) {
//百度贴吧的uri地址
String uri = "https://tieba.baidu.com/f"; // --> /f:就是二级地址:注意地址一定要正确哦!一不小心就会404
//1、创建HttpClient连接
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
//1.5、封装GET请求的参数
URIBuilder uriBuilder = new URIBuilder(uri);
//第一种:setParameter放参数
uriBuilder.setParameter("kw", "乘风破浪的姐姐");
//uriBuilder.setParameter("kw","乘风破浪的姐姐").setParameter("t","其他参数");
//第二种:放参数
//List<NameValuePair> params = new ArrayList<>();
//params.add(new BasicNameValuePair("kw", "乘风破浪的姐姐"));
//params.add(new BasicNameValuePair("t", "其他"));
//uriBuilder.setParameters(params);
//第三种:放参数
//uriBuilder.setParameters(new BasicNameValuePair("kw", "乘风破浪的姐姐"),
// new BasicNameValuePair("t", "其他参数"));
//2、创建HtpGet请求:uriBuilder.build()
HttpGet httpGet = new HttpGet(uriBuilder.build());
//3、HttpClient发送请求
response = httpClient.execute(httpGet);
//4、拿到请求页面的返回数据,请求成功才有数据啊!
HttpEntity entity = null;
if (response != null && response.getStatusLine().getStatusCode() == 200) {
//获取服务器返回的实体数据
entity = response.getEntity();
//把实体数据转换成指定类型的字符串
String context = EntityUtils.toString(entity, "utf8");
System.out.println(context);
}
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
} finally {
//不管如何关闭响应、请求的连接
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
拿到的响应数据部分截图:
HttpPost请求
同HttpGet请求一样,请求百度贴吧的地址,细看之下,POST请求和GET请求是一样地。
//HttpClient发送POST请求
public class HttpPostRequest {
public static void main(String[] args) {
String uri = "https://tieba.baidu.com";
//1、创建客户端,建立连接
CloseableHttpClient httpClient = HttpClients.createDefault();
//2、创建POST请求
HttpPost httpPost = new HttpPost(uri);
CloseableHttpResponse response = null;
try {
//3、发送请求
response = httpClient.execute(httpPost);
//4、获取响应数据
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
String context = EntityUtils.toString(entity, "utf-8");
System.out.println(context);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//不管如何关闭响应、请求的连接
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
返回数据部分截图:
HttpPost带参请求(提交表单数据)
POST请求一般用来提交表单数据,下面就是 POST带参请求的示例,同样以和HttpGet带参请求相同的地址乘风破浪的姐姐
为例:
//由于篇幅的原因,异常不捕捉,直接抛出去了
//HttpClient发送带参POST请求
public class HttpPostRequestParam {
public static void main(String[] args) throws IOException {
String uri = "https://tieba.baidu.com/f";
//1、创建客户端,建立连接
CloseableHttpClient httpClient = HttpClients.createDefault();
//1.5、封装表单参数
//********************************************
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("kw", "乘风破浪的姐姐"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params);
//2、创建HttpPost请求
HttpPost httpPost = new HttpPost(uri);
//设置表单参数到请求体
httpPost.setEntity(formEntity);
//********************************************
//3、发送数据
CloseableHttpResponse response = httpClient.execute(httpPost);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
//4、获取数据
HttpEntity entity = response.getEntity();
String context = EntityUtils.toString(entity, "utf-8");
System.out.println(context);
}
//关闭资源
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
}
}
获取到返回的数据:
仔细对比之下,HttpGet请求和HttpPost请求除了参数的封装方式不一样之外其他的全部都是相同的。
HttpClient连接池+请求配置
httpClient连接池就类似于数据库连接池一样,从一个池子里里面获取连接。
从上面的示例可以看出,每一个代码后面都有一个finally
代码块中的代码去关闭资源,而频繁的创建、关闭资源对性能的影响是很大的(就相当于每次打开浏览器,再关闭),所以在这里有了HttpClient连接池的概念。
连接池准备好HttpClient(先打开一定数量的浏览器)每次请求从连接池中获取一个HttpClient连接(随便拿到一个已经打开的浏览器使用),使用完成后HttpClient再归还到连接池中(让别人使用)。
下面的示例就是创建连接池以及设置请求配置的步骤,除此之外,无论是GET请求还是POST请求都无变化。
//HttpClient连接池
public class HttpClientPool {
public static void main(String[] args) throws IOException {
//创建HttpClient连接池:使用连接池管理器发起请求
PoolingHttpClientConnectionManager pm = new PoolingHttpClientConnectionManager();
//设置连接池最大连接数量
pm.setMaxTotal(100);
//设置每个主机(访问的目标主机)的最大连接数
//每一个相同的主机最多获取10个连接数量:连接可以尽可能的达到一个数据均衡的目的
pm.setDefaultMaxPerRoute(10);
//设置请求设置:部分
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) //设置连接最长时间5000毫秒
.setConnectTimeout(500) //创建连接的最长时间:ms
.setSocketTimeout(10 * 1000).build(); //设置数据传输的最长时间
//设置请求信息
doGet(pm, requestConfig);
doGet(pm, requestConfig);
}
private static void doGet(PoolingHttpClientConnectionManager pm, RequestConfig config) throws IOException {
//不每次都创建新的HttpClient,而是从连接池管理器中获取连接
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(pm).build();
//下面的部分就相同了
String uri = "https://www.baidu.com/";
HttpGet httpGet = new HttpGet(uri);
//设置请求信息
httpGet.setConfig(config);
//
CloseableHttpResponse response = httpClient.execute(httpGet);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
String content = EntityUtils.toString(entity, "utf-8");
System.out.println(content);
}
//关闭响应
response.close();
//注意!这就不用关闭HttpClient了,因为连接通过连接池管理了
//httpClient.close();
}
}
还没有评论,来说两句吧...