一、概述
这里只针对4.5的版本进行介绍。
在项目中经常有需要发送http请求的场景,httpclient很好的解决了这个问题,而且非常易用。
org.apache.httpcomponents
httpclient
4.5
// 创建客户端
CloseableHttpClient httpclient = HttpClients.createDefault();
//创建一个get请求
HttpGet httpget = new HttpGet("https://api.douban.com/v2/book/1220562");
CloseableHttpResponse response = null;
try {
//发送请求并获取返回结果
response = httpclient.execute(httpget);
if(HttpStatus.SC_OK == response.getStatusLine().getStatusCode()){//判断状态码
HttpEntity httpEntity = response.getEntity(); //获取返回body
String result = EntityUtils.toString(httpEntity,"UTF-8");// 转成string
System.out.println("result:"+result);
}
} catch(IOException ioe){
}finally {
try{
if(response != null){
response.close(); //释放连接
}
}catch(Exception e){}
try{
if(httpclient != null){
httpclient.close();//关闭客户端
}
}catch(Exception e){}
}
上面是一个非常简单的示例,创建客户端-->创建请求-->发送请求并获取返回结果-->处理返回结果-->关闭连接,流程很清晰。
在生产环境中,我们是不会直接使用
CloseableHttpClient httpclient = HttpClients.createDefault();
这种方式来创建httpclient的。因为这种方式忽略了许多配置,例如最大连接数,请求配置,很有可能导致生产环境出问题。在生产环境中,我们采用自定义的方式创建客户端,例如:
RequestConfig requestConfig = RequestConfig //请求设置
.custom()
.setConnectionRequestTimeout(ConnectionRequestTimeout) //从连接池获取连接超时时间
.setConnectTimeout(ConnectionTimeout) //连接超时时间
.setSocketTimeout(SocketTimeout).build(); //套接字超时时间
HttpClientBuilder builder = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setMaxConnTotal(MaxConnTotal); //设置最大连接数
httpClient = builder.build();
这是一个比较通用的httpclient。其实还有很多配置没有列出来,可以参考官网。
最简单的get请求如下所示:
//创建一个get请求
HttpGet httpget = new HttpGet("https://api.douban.com/v2/book/1220562");
如果有查询参数,可以直接拼接到url里面。如果嫌拼接麻烦,可以通过工具类URIBuilder实现:
//创建一个get请求
URI uri = null;
try{
uri = new URIBuilder()
.setScheme("https")
.setHost("api.douban.com")
.setPath("/v2/movie/in_theaters")
.setParameter("city", "北京")
.build();
}catch(URISyntaxException e){
System.out.println("uri语法错误");
}
HttpGet httpget = new HttpGet(uri);
这样请求的地址最后就会变成:https://api.douban.com/v2/movie/in_theaters?city=北京。
post提交数据一般有两种,表单提交和payload提交方式,写法稍微有点不同。
//2-发送表单数据
HttpPost request2 = new HttpPost(url);
List formparams = new ArrayList();
formparams.add(new BasicNameValuePair("name", "gameloft9"));//添加参数
formparams.add(new BasicNameValuePair("pwd", "123456"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
request2.setEntity(entity);
//发送请求并获取返回结果
response = httpclient.execute(request2);
// 1-发送json数据
HttpPost request = new HttpPost(url);
String json = "{\n" +
" \"name\":\"gameloft9\",\n" +
" \"pwd\":\"123456\"\n" +
"}";
StringEntity stringEntity = new StringEntity(json, "UTF-8");
stringEntity.setContentType("application/json");
request.setEntity(stringEntity);
//发送请求并获取返回结果
response = httpclient.execute(request);
调用httpclient.execute()方法后,会阻塞直到返回结果或者超时异常,我们通过CloseableHttpResponse对象接受返回结果。从response里面我们可以拿到很多东西,比如状态码,header和我们最关心的body内容。
response.getStatusLine().getStatusCode(); //获取状态码
response.getHeaders();//获取头
HttpEntity httpEntity = response.getEntity(); //获取返回内容
我们可以通过下面两个方法读取内容:
InputStream getContent() throws IOException, UnsupportedOperationException;
void writeTo(OutputStream var1) throws IOException;
如果返回的是string类型的数据,官方很贴心给了一个EntityUtils工具类,通过下面的方法可以直接读取出内容。
String result = EntityUtils.toString(httpEntity, "UTF-8");// 转成string
一般的json报文都可以通过这种方式进行处理。
返回的httpEntity只能读取一次,如果想多次使用,需要用BufferedHttpEntity进行包装:
HttpEntity httpEntity = response.getEntity(); //获取返回body
httpEntity = new BufferedHttpEntity(httpEntity); //包装一下,以便可以重复读取
处理完成后需要关闭流(针对getContent()处理,防止忘记关闭inputstream)
EntityUtils.consume(httpEntity);
最后在finnaly里面需要释放资源和客户端,
try{
if(response != null){
response.close(); //关闭
}
}catch(Exception e){}
try{
if(httpclient != null){
httpclient.close();//关闭客户端
}
}catch(Exception e){}
以上就是httpclient的基本用法,后续会更深入的讲解其他方面的内容。