org.apache.httpcomponents下的httpclient使用

一、概述

      这里只针对4.5的版本进行介绍。

      在项目中经常有需要发送http请求的场景,httpclient很好的解决了这个问题,而且非常易用。

maven依赖
<dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5</version>
    </dependency>
一个最简单的demo
// 创建客户端
        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请求如下所示:

 //创建一个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请求

post提交数据一般有两种,表单提交和payload提交方式,写法稍微有点不同。

表单提交
 //2-发送表单数据
            HttpPost request2 = new HttpPost(url);
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            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);
payload提交
  // 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的基本用法,后续会更深入的讲解其他方面的内容。

猜你喜欢

转载自blog.csdn.net/gameloft9/article/details/80309575