龙空技术网

java处理http请求之Apache httpClient入门教程

充满元气的java爱好者 306

前言:

现在姐妹们对“apachehttp请求处理流程”大约比较关心,你们都想要分析一些“apachehttp请求处理流程”的相关资讯。那么小编在网络上搜集了一些有关“apachehttp请求处理流程””的相关内容,希望看官们能喜欢,我们快快来学习一下吧!

一、项目介绍

Apache 提供用来做http请求的项目有两个,3.x 版本的项目叫做 The Commons HttpClient。

它一开始是 Apache Jakarta Common 下的子项目,后来独立出去了,现在这个项目已经结束了它的生命周期,不再开发和维护。

取而代之的是 4.x 版本的 Apache Httpcomponents 项目,它包括 HttpClient 和 HttpCore 两大模块,能提供更好的性能和更大的灵活性。

二、项目模块

Apache Httpcomponents 项目包括 HttpClient 和 HttpCore 两大模块,其中,HttpCore 是一套HTTP协议实现包。而 HttpClient 是基于HttpCore的一套客户端。

三、使用方式

使用 Httpclient 需要经过如下步骤

创建 HttpClient创建 http 请求,如 HttpGetHttpPost添加请求参数添加请求设置,如超时等使用 HttpClient 执行 http 请求读取返回内容并释放连接3.1 创建HttpClient3.1.1 创建默认客户端:

复制代码1JAVA    CloseableHttpClient httpclient = HttpClients.createDefault();

一些重要的默认配置:

默认连接池大小10,每域名最大连接5连接池中连接存活时间 connTimeToLive = -1 ,默认单位为毫秒,默认连接不失效域名验证器为 DefaultHostnameVerifier , 会验证域名SSL 上下文为 SSLContext.getInstance("TLS"),没有使用密钥管理器(KeyManager)和信任管理器(TrustManager)3.1.2 自定义客户端失败不重试

复制代码1JAVA    CloseableHttpClient client = HttpClients.custom().setRetryHandler((e, i, c) -> false).build();
自定义连接池
复制代码12345678910111213141516171819202122232425262728JAVA //设置自定义连接池    @Test    public void customConnectionPool() throws Exception {        //1.创建 https 需要的 SslContext 相关内容        //1.1 创建 SslContext        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());        ks.load(new FileInputStream("证书文件"), "密码".toCharArray());        SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(TrustAllStrategy.INSTANCE)                .loadKeyMaterial(ks, "证书密码".toCharArray()).build();        //1.2 创建 SSLConnectionSocketFactory        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv3", "TLSv1.1", "TLSv1.2"}, null,                NoopHostnameVerifier.INSTANCE);        //2.创建连接池        //2.1 构建协议 registry        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()                .register("http", PlainConnectionSocketFactory.getSocketFactory())                .register("https", sslConnectionSocketFactory)                .build();        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registry);        //3.连接池针对所有连接、每域名的连接的数量设置        poolingHttpClientConnectionManager.setMaxTotal(100);        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(20);        //4.创建client        CloseableHttpClient client =        HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build();    }
3.2 创建 Http 请求

创建 HttpGet、HttpPost 请求

复制代码12345678910JAVA    @Test    public void getAndPost(){        //1.创建get请求        HttpGet get = new HttpGet(";);        //2.创建post请求        HttpPost post = new HttpPost(";);        //3.其他如 HttpPut、HttpOptions、HttpTrace、HttpDelete、HttpPatch    }
3.3 添加请求参数
复制代码12345678910111213141516171819202122232425262728293031323334353637383940JAVA    @Test    public void addParams() throws IOException {        HttpPost post = new HttpPost(";);        //1.底层流,基础参数        BasicHttpEntity basicHttpEntity = new BasicHttpEntity();        //1.1添加参数内容        InputStream bis = new ByteArrayInputStream("参数".getBytes());        basicHttpEntity.setContent(bis);        //1.2设置内容长度        basicHttpEntity.setContentLength(bis.available());        //1.3取消分块发送        basicHttpEntity.setChunked(false);        post.setEntity(basicHttpEntity);        //2.字节码类型参数        HttpEntity entity = new ByteArrayEntity("name=zhangsan&age=100".getBytes());        post.setEntity(entity);        //3.字符串类型参数        entity = new StringEntity("name=zhangsan&age=100");        post.setEntity(entity);        //4.流式参数,用法与BasicHttpEntity类似,内容和长度严格匹配        entity = new InputStreamEntity(bis,bis.available());        post.setEntity(entity);        //5.文件类型参数        entity = new FileEntity(new File("上传文件"));        post.setEntity(entity);        //6.添加请求头        post.addHeader("Content-Type","text/html;charset=UTF-8");        Header contentType = new BasicHeader("Content-Type","text/html;charset=UTF-8");        post.addHeader(contentType);        Header host = new BasicHeader("Host",";);        post.setHeaders(new Header[]{contentType,host});    }
3.4 添加请求设置
复制代码123456789101112131415JAVA    @Test    public void requestConfig(){        //1.配置RequestConfig        RequestConfig requestConfig = RequestConfig.custom()        .setConnectionRequestTimeout(10000) //从连接池获取可用连接的超时时间,单位毫秒        .setSocketTimeout(5000) //请求获取数据的超时时间        .setConnectTimeout(4000) //连接超时时间        .build();        HttpPost post = new HttpPost(";);        //2.设置到post请求当中        post.setConfig(requestConfig);        //也可以当作默认值,设置到client当中,此client都会按这个超时处理        CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();    }
3.4.1 超时时间说明

超时类型

说明

connectionTimeout

连接建立时间,即3次握手时间,默认值-1

socketTimeout

连接后,数据传输过程中数据包之间间隔的最大时间,默认值-1

connectionRequestTimeout

从连接池获取连接的超时时间,默认值-1

注意:

socketTimeout 和 connectionRequestTimeout 如果不设置,请求会阻塞。

但是 connectionTimeout 的情况有所不同,它依赖于各平台的 socket 超时时间设置。

windows 10 实测为 20s, linux 平台则不定,它会按 /proc/sys/net/ipv4/tcp_syn_retries 中配置的次数重试,一般为3s\7s\15s\31s\63s递增

另外,即使 java 程序返回了超时结果,但是linux服务器依旧在执行重试直到服务器端超时,为了提高资源利用率,可以手动关闭

关于 linux socket 超时的问题,请参阅 无悔的湖光-Al 的 从linux源码看socket(tcp)的timeout

3.5 执行 http 请求

执行 http 请求比较简单,直接调用 execute() 方法即可

复制代码12345678910JAVA    @Test    public void execute(){        CloseableHttpClient client = HttpClients.createDefault();        try {            client.execute(new HttpPost(";));            client.execute(new HttpGet(";));        } catch (IOException e) {            e.printStackTrace();        }    }
3.6 读取返回内容并释放连接

服务器返回结果被封装到 HttpResponse 对象里,我们可以从这里拿到我们想要的返回结果

复制代码123456789101112131415161718192021222324252627282930313233343536373839404142434445JAVA    @Test    public void getResponse() {        CloseableHttpClient client = HttpClients.createDefault();        CloseableHttpResponse httpResponse = null;        final HttpGet httpGet = new HttpGet(";);        try {            httpResponse = client.execute(httpGet);            //1.获取返回状态            System.out.println(httpResponse.getStatusLine().getStatusCode());            //2.获取返回头信息            Header[] headers = httpResponse.getAllHeaders();            for (Header header : headers) {                System.out.println(header.getName() + ":" + header.getValue());            }            //3.获取返回消息体            HttpEntity entity = httpResponse.getEntity();            if(null != entity){                //3.1 得到返回结果并关闭流,与下面的只能执行一个,因为流只能读取一次                String content = EntityUtils.toString(entity);                System.out.println(content);                //3.2 得到返回结果并关闭流,与上面的只能执行一个//              byte[] contents = EntityUtils.toByteArray(entity);            }        } catch (IOException e) {            e.printStackTrace();        } finally {            if (null != httpResponse) {                //4.归还连接到连接池                try {                    httpResponse.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            //如果复用 httpGet ,则重置其状态使其可以重复使用            httpGet.releaseConnection();        }        //只在应用关闭的时候关闭client        try {            client.close();        } catch (IOException e) {            e.printStackTrace();        }    }

原文链接:java处理http请求之Apache httpClient入门教程 - 去哪里吃鱼 - 博客园 (cnblogs.com)

标签: #apachehttp请求处理流程 #apachehttpcient #apache请求处理过程 #apachecxfwebclient #apache处理post请求