HttpClient4.5入门实例教程

Apache HttpClient 5 使用详细教程 转存失败重新上传取消超文本传输协议(HTTP)可能是当今互联网上最重要的协议之一,Web 服务、微服务以及支持网络的各种设备上的服务几乎都是 HTTP 协议,HTTP 协议已经从 Web 浏览器走向了更广泛的使用场景。虽然java.net包已经提供了 HTTP 访问资源的基本功能,但是它不够灵活,而且不能随心所欲的进行自定义。... 阅读详情

前言

旧版本的HttpClient已经停止维护了,它已经被Apache HttpComponents项目的HttpClient和HttpCore模块替代。Hyper-Text Transfer Protocol (HTTP)也许是当今互联网上使用的最为重要的协议。虽然java.net package提供了基本的从HTTP获取资源的功能,但是它不提供全面的灵活性或许多应用程序所需的功能。HttpClient试图填补这一空白,通过提供一个有效的、最新的、功能丰富的方案实现客户端最近的HTTP标准和建议。注意HttpClient不是浏览器,而是一个客户端HTTP传输库,目的是传送和接收HTTP信息,它缺少浏览器需要的UI, HTML渲染器和JavaScript引擎。
可以直接到官网下载,或者使用maven配置。HttpClient 4.5 需要Java 1.5或者更新的版本。
  1.  <dependency>  
  2.     <groupId>org.apache.httpcomponents</groupId>  
  3.     <artifactId>httpcore</artifactId>  
  4.     <version>4.4.6</version>  
  5. </dependency>  
  6. <dependency>  
  7.     <groupId>org.apache.httpcomponents</groupId>  
  8.     <artifactId>httpclient</artifactId>  
  9.     <version>4.5.3</version>  
  10. </dependency>  
 <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.6</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

HttpClient最基本的功能是执行HTTP方法,执行一个HTTP方法包含了一个或者几个的HTTP REQUEST/HTTP RESPONSE交换,这通常在HttpClient内部处理。用户提供一个被执行的请求对象,HttpClient传送这个请求到目标服务器并且返回一个对应的响应对象,或者当请求不成功时抛出一个异常。所有的HTTP请求都有一行,它包含了请求请求方法名、请求URI和HTTP协议版本(1.0或者1.1)。


请求

HttpClient支持开箱即用的,所有定义在HTTP/1.1规范中的方法:GET、HEAD、POST、PUT、DELETE、TRACE、OPTIONS。每个方法类型都有一个指定的类:HttpGet、HttpHead、HttpPost、HttpPut、HttpDelete、HttpTrace、HttpOptions。

  1. HttpGet httpget = new HttpGet(  
  2.      ”http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=”);  
HttpGet httpget = new HttpGet(
     "http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=");

HttpClient也提供了URIBuilder用于构建URI。

  1. URI uri = new URIBuilder()  
  2.         .setScheme(”http”)  
  3.         .setHost(”www.google.com”)  
  4.         .setPath(”/search”)  
  5.         .setParameter(”q”, “httpclient”)  
  6.         .setParameter(”btnG”, “Google Search”)  
  7.         .setParameter(”aq”, “f”)  
  8.         .setParameter(”oq”, “”)  
  9.         .build();  
  10. HttpGet httpget = new HttpGet(uri);  
  11. System.out.println(httpget.getURI());//http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=  
URI uri = new URIBuilder()
        .setScheme("http")
        .setHost("www.google.com")
        .setPath("/search")
        .setParameter("q", "httpclient")
        .setParameter("btnG", "Google Search")
        .setParameter("aq", "f")
        .setParameter("oq", "")
        .build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());//http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=


响应

HTTP响应是服务端在接收和处理客户端消息后返回给客户端的消息。消息的第一行包含了协议版本,紧接着是状态码和状态码描述文字。

  1. HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, “OK”);  
  2.   
  3. System.out.println(response.getProtocolVersion());//HTTP/1.1  
  4. System.out.println(response.getStatusLine().getStatusCode());//200  
  5. System.out.println(response.getStatusLine().getReasonPhrase());//OK  
  6. System.out.println(response.getStatusLine().toString());//HTTP/1.1 200 OK  
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");

System.out.println(response.getProtocolVersion());//HTTP/1.1
System.out.println(response.getStatusLine().getStatusCode());//200
System.out.println(response.getStatusLine().getReasonPhrase());//OK
System.out.println(response.getStatusLine().toString());//HTTP/1.1 200 OK


消息头

HTTP消息可以包含一些用来描述消息属性的头部消息,例如content length, content type等等。HttpClient提供了方法来检索、增加、删除、列举头部消息。
  1. HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,   
  2.     HttpStatus.SC_OK, ”OK”);  
  3. response.addHeader(”Set-Cookie”,   
  4.     ”c1=a; path=/; domain=localhost”);  
  5. response.addHeader(”Set-Cookie”,   
  6.     ”c2=b; path=\”/\”, c3=c; domain=\”localhost\”“);  
  7. Header h1 = response.getFirstHeader(”Set-Cookie”);  
  8. System.out.println(h1);//Set-Cookie: c1=a; path=/; domain=localhost  
  9. Header h2 = response.getLastHeader(”Set-Cookie”);  
  10. System.out.println(h2);//Set-Cookie: c2=b; path=”/”, c3=c; domain=”localhost”  
  11. Header[] hs = response.getHeaders(”Set-Cookie”);  
  12. System.out.println(hs.length);//2  
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
    HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie", 
    "c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie", 
    "c2=b; path=\"/\", c3=c; domain=\"localhost\"");
Header h1 = response.getFirstHeader("Set-Cookie");
System.out.println(h1);//Set-Cookie: c1=a; path=/; domain=localhost
Header h2 = response.getLastHeader("Set-Cookie");
System.out.println(h2);//Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
Header[] hs = response.getHeaders("Set-Cookie");
System.out.println(hs.length);//2
最有效的方法还是利用HeaderIterator

  1. HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,   
  2.     HttpStatus.SC_OK, ”OK”);  
  3. response.addHeader(”Set-Cookie”,   
  4.     ”c1=a; path=/; domain=localhost”);  
  5. response.addHeader(”Set-Cookie”,   
  6.     ”c2=b; path=\”/\”, c3=c; domain=\”localhost\”“);  
  7.   
  8. HeaderIterator it = response.headerIterator(”Set-Cookie”);  
  9.   
  10. while (it.hasNext()) {  
  11.     System.out.println(it.next());  
  12. }  
  13. st  
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
    HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie", 
    "c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie", 
    "c2=b; path=\"/\", c3=c; domain=\"localhost\"");

HeaderIterator it = response.headerIterator("Set-Cookie");

while (it.hasNext()) {
    System.out.println(it.next());
}
st
同样,它也提供了将头部消息解析成单个元素的方法

  1. HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,   
  2.     HttpStatus.SC_OK, ”OK”);  
  3. response.addHeader(”Set-Cookie”,   
  4.     ”c1=a; path=/; domain=localhost”);  
  5. response.addHeader(”Set-Cookie”,   
  6.     ”c2=b; path=\”/\”, c3=c; domain=\”localhost\”“);  
  7.   
  8. HeaderElementIterator it = new BasicHeaderElementIterator(  
  9.     response.headerIterator(”Set-Cookie”));  
  10.   
  11. while (it.hasNext()) {  
  12.     HeaderElement elem = it.nextElement();   
  13.     System.out.println(elem.getName() + ” = ” + elem.getValue());  
  14.     NameValuePair[] params = elem.getParameters();  
  15.     for (int i = 0; i < params.length; i++) {  
  16.         System.out.println(” ” + params[i]);  
  17.     }  
  18. }  
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
    HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie", 
    "c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie", 
    "c2=b; path=\"/\", c3=c; domain=\"localhost\"");

HeaderElementIterator it = new BasicHeaderElementIterator(
    response.headerIterator("Set-Cookie"));

while (it.hasNext()) {
    HeaderElement elem = it.nextElement(); 
    System.out.println(elem.getName() + " = " + elem.getValue());
    NameValuePair[] params = elem.getParameters();
    for (int i = 0; i < params.length; i++) {
        System.out.println(" " + params[i]);
    }
}
输出

  1. c1 = a  
  2. path=/  
  3. domain=localhost  
  4. c2 = b  
  5. path=/  
  6. c3 = c  
  7. domain=localhost  
c1 = a
path=/
domain=localhost
c2 = b
path=/
c3 = c
domain=localhost

HTTP实体

HTTP消息可以包含内容实体,HTTP定义了两个实体封装请求方法:PUT和POST。HttpClient依靠内容的来源来区分三种实体。
streamed:内容来源于流或者动态生成,特别是,包含从HTTP响应接收的实体,streamed实体一般不可重复生成的。
self-contained:内容位于内存中或者是可获得的,意味着它是独立于连接和其他实体的,Self-contained实体一般可重复,这种类型的实体大都用于HTTP请求的封装。
wrapping:内容来源于其他实体。
对于连接管理来说,当从HTTP响应中用流输出内容的时候这些区分的重要的。对于仅仅由应用程序创建并且用HttpClient发送的请求实体来说,streamed和self-contained的区别是不重要的。既然如此,那么就认为不可重复的实体是streamed,可重复的实体是self-contained。
可重复的实体,表示它的内容可以不止一次被读取,例如ByteArrayEntity和StringEntity。为了读取内容,任何人都可以使用HttpEntity#getContent()返回Java.io.InputStream,或者用HttpEntity#writeTo(OutputStream)提供给输出流。
当实体通过一个收到的报文获取时,HttpEntity#getContentType()方法和HttpEntity#getContentLength()方法可以用来读取通用的元数据,如Content-Type和Content-Length头部信息(如果它们是可用的)。因为头部信息Content-Type可以包含对文本MIME类型的字符编码,比如text/plain或text/html,HttpEntity#getContentEncoding()方法用来读取这个信息。如果头部信息Content-Length不可用,那么就返回长度-1,而对于内容类型返回NULL。如果头部信息Content-Type是可用的,那么就会返回一个Header对象。

  1. StringEntity myEntity = new StringEntity(“important message”,   
  2.    ContentType.create(”text/plain”, “UTF-8”));  
  3. System.out.println(myEntity.getContentType());  
  4. System.out.println(myEntity.getContentLength());  
  5. System.out.println(EntityUtils.toString(myEntity));  
  6. System.out.println(EntityUtils.toByteArray(myEntity).length);  
StringEntity myEntity = new StringEntity("important message", 
   ContentType.create("text/plain", "UTF-8"));
System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);
输出

  1. Content-Type: text/plain; charset=utf-8  
  2. 17  
  3. important message  
  4. 17  
Content-Type: text/plain; charset=utf-8
17
important message
17


确保低级别资源释放

为了确保适当地释放系统资源,任何人必须关闭实体相关的流或者response本身。关闭实体相关的流和response的区别是:前者是通过消耗实体内容保持连接可用,后者直接关闭和抛弃连接。请记住,HttpEntity#writeTo(OutputStream)一旦实体被完全写出,也需要保证系统资源适当地释放。 EntityUtils#consume(HttpEntity)可以保证实体内容被完全消耗并且底层的流被关闭。
  1. CloseableHttpClient httpclient = HttpClients.createDefault();  
  2. HttpGet httpget = new HttpGet(“http://localhost/”);  
  3. CloseableHttpResponse response = httpclient.execute(httpget);  
  4. try {  
  5.     HttpEntity entity = response.getEntity();  
  6.     if (entity != null) {  
  7.         InputStream instream = entity.getContent();  
  8.         try {  
  9.             // do something useful  
  10.         } finally {  
  11.             instream.close();  
  12.         }  
  13.     }  
  14. } finally {  
  15.     response.close();  
  16. }  
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        InputStream instream = entity.getContent();
        try {
            // do something useful
        } finally {
            instream.close();
        }
    }
} finally {
    response.close();
}
有些情况下,仅仅response的一小部分需要被取回并且消耗内容的剩余部分且保持连接可用的性能代价是很高的,这种情况下可以直接关闭response。

  1. CloseableHttpClient httpclient = HttpClients.createDefault();  
  2. HttpGet httpget = new HttpGet(”http://localhost/”);  
  3. CloseableHttpResponse response = httpclient.execute(httpget);  
  4. try {  
  5.     HttpEntity entity = response.getEntity();  
  6.     if (entity != null) {  
  7.         InputStream instream = entity.getContent();  
  8.         int byteOne = instream.read();  
  9.         int byteTwo = instream.read();  
  10.         // Do not need the rest  
  11.     }  
  12. } finally {  
  13.     response.close();  
  14. }  
CloseableHttpClient httpclient = HttpClients.createDefault(); 
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
int byteOne = instream.read();
int byteTwo = instream.read();
// Do not need the rest
}
} finally {
response.close();
}

消耗实体内容

推荐的消耗实体内容的方法是HttpEntity#getContent()和HttpEntity#writeTo(OutputStream),但是EntityUtils类有一些静态方法,这些方法可以更加容易地从实体中读取内容或信息。代替直接读取java.io.InputStream,也可以使用这个类中的方法以字符串/字节数组的形式获取整个内容体。然而,EntityUtils的使用是强烈不鼓励的,除非响应实体源自可靠的HTTP服务器和已知的长度限制。
  1. CloseableHttpClient httpclient = HttpClients.createDefault();  
  2. HttpGet httpget = new HttpGet(“http://localhost/”);  
  3. CloseableHttpResponse response = httpclient.execute(httpget);  
  4. try {  
  5.     HttpEntity entity = response.getEntity();  
  6.     if (entity != null) {  
  7.         long len = entity.getContentLength();  
  8.         if (len != -1 && len < 2048) {  
  9.             System.out.println(EntityUtils.toString(entity));  
  10.         } else {  
  11.             // Stream content out  
  12.         }  
  13.     }  
  14. } finally {  
  15.     response.close();  
  16. }  
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        long len = entity.getContentLength();
        if (len != -1 && len < 2048) {
            System.out.println(EntityUtils.toString(entity));
        } else {
            // Stream content out
        }
    }
} finally {
    response.close();
}
在一些情况下可能会不止一次的读取实体。此时实体内容必须以某种方式在内存或磁盘上被缓冲起来。最简单的方法是通过使用BufferedHttpEntity类来包装源实体完成。这会引起源实体内容被读取到内存的缓冲区中。在其它所有方式中,实体包装器将会得到源实体。
  1. CloseableHttpResponse response = <…>  
  2. HttpEntity entity = response.getEntity();  
  3. if (entity != null) {  
  4.     entity = new BufferedHttpEntity(entity);  
  5. }  
CloseableHttpResponse response = <...>
HttpEntity entity = response.getEntity();
if (entity != null) {
    entity = new BufferedHttpEntity(entity);
}

生成实体内容

HttpClient提供一些类,它们可以用于通过HTTP连接有效地生成内容。这些类的实例可以和实体包装请求例如POST和PUT相关联以便包装实体内容。HttpClient提供了几个最为常见的数据容器,比如字符串,字节数组,输入流和文件提供了一些类:StringEntity,ByteArrayEntity,InputStreamEntity和FileEntity。请注意InputStreamEntity是不可重复的,因为它仅仅能从低层数据流中读取一次内容。通常来说,我们推荐实现一个定制的HttpEntity类,这是自我包含式的,用来代替使用通用的InputStreamEntity。FileEntity是一个很好的起点,FileEntity继承HttpEntity。

  1. File file = new File(“somefile.txt”);  
  2. FileEntity entity = new FileEntity(file,   
  3.     ContentType.create(”text/plain”, “UTF-8”));          
  4.   
  5. HttpPost httppost = new HttpPost(”http://localhost/action.do”);  
  6. httppost.setEntity(entity);  
File file = new File(“somefile.txt”); 
FileEntity entity = new FileEntity(file,
ContentType.create(“text/plain”, “UTF-8”));

HttpPost httppost = new HttpPost(“http://localhost/action.do“);
httppost.setEntity(entity);

HTML表单

许多应用需要模拟表单提交,比如,想要记录一个Web应用程序或提交输入数据。HttpClient提供了实体类UrlEncodedFormEntity使之更容易实现。
  1. List<NameValuePair> formparams = new ArrayList<NameValuePair>();  
  2. formparams.add(new BasicNameValuePair(“param1”, “value1”));  
  3. formparams.add(new BasicNameValuePair(“param2”, “value2”));  
  4. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);  
  5. HttpPost httppost = new HttpPost(“http://localhost/handler.do”);  
  6. httppost.setEntity(entity);  
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("param1", "value1"));
formparams.add(new BasicNameValuePair("param2", "value2"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
HttpPost httppost = new HttpPost("http://localhost/handler.do");
httppost.setEntity(entity);

内容分块

一般来说,推荐让HttpClient自己根据Http消息传递的特征来选择最合适的传输编码。当然,如果非要手动控制也是可以的,设置HttpEntity#setChunked()为true,可以分块传输,但是如果是HTTP/1.0,那么这个设置就会被忽略,值有HTTP/1.1才支持。

  1. StringEntity entity = new StringEntity(“important message”,  
  2.         ContentType.create(”plain/text”, Consts.UTF_8));  
  3. entity.setChunked(true);  
  4. HttpPost httppost = new HttpPost(“http://localhost/acrtion.do”);  
  5. httppost.setEntity(entity);  
StringEntity entity = new StringEntity("important message",
        ContentType.create("plain/text", Consts.UTF_8));
entity.setChunked(true);
HttpPost httppost = new HttpPost("http://localhost/acrtion.do");
httppost.setEntity(entity);

response处理

最简单也是最方便的处理http响应的方法就是使用ResponseHandler接口,这个接口中有handleResponse(HttpResponse response)方法。使用这个方法,用户完全不用关心http连接管理器。当使用ResponseHandler时,HttpClient会自动地将Http连接释放给Http管理器,即使http请求失败了或者抛出了异常。
  1. CloseableHttpClient httpclient = HttpClients.createDefault();  
  2. HttpGet httpget = new HttpGet(“http://localhost/json”);  
  3.   
  4. ResponseHandler<MyJsonObject> rh = new ResponseHandler<MyJsonObject>() {  
  5.   
  6.     @Override  
  7.     public JsonObject handleResponse(  
  8.             final HttpResponse response) throws IOException {  
  9.         StatusLine statusLine = response.getStatusLine();  
  10.         HttpEntity entity = response.getEntity();  
  11.         if (statusLine.getStatusCode() >= 300) {  
  12.             throw new HttpResponseException(  
  13.                     statusLine.getStatusCode(),  
  14.                     statusLine.getReasonPhrase());  
  15.         }  
  16.         if (entity == null) {  
  17.             throw new ClientProtocolException(“Response contains no content”);  
  18.         }  
  19.         Gson gson = new GsonBuilder().create();  
  20.         ContentType contentType = ContentType.getOrDefault(entity);  
  21.         Charset charset = contentType.getCharset();  
  22.         Reader reader = new InputStreamReader(entity.getContent(), charset);  
  23.         return gson.fromJson(reader, MyJsonObject.class);  
  24.     }  
  25. };  
  26. MyJsonObject myjson = client.execute(httpget, rh);  
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/json");

ResponseHandler<MyJsonObject> rh = new ResponseHandler<MyJsonObject>() {

    @Override
    public JsonObject handleResponse(
            final HttpResponse response) throws IOException {
        StatusLine statusLine = response.getStatusLine();
        HttpEntity entity = response.getEntity();
        if (statusLine.getStatusCode() >= 300) {
            throw new HttpResponseException(
                    statusLine.getStatusCode(),
                    statusLine.getReasonPhrase());
        }
        if (entity == null) {
            throw new ClientProtocolException("Response contains no content");
        }
        Gson gson = new GsonBuilder().create();
        ContentType contentType = ContentType.getOrDefault(entity);
        Charset charset = contentType.getCharset();
        Reader reader = new InputStreamReader(entity.getContent(), charset);
        return gson.fromJson(reader, MyJsonObject.class);
    }
};
MyJsonObject myjson = client.execute(httpget, rh);

HttpClient的接口

HttpClient的接口代表了请求执行过程中最基本的契约,HttpClient接口没有对Http请求的过程做特别的限制和详细的规定,连接管理、状态管理、认证处理和重定向处理这些功能都单独实现。这样就能更加容易地给接口添加额外的功能例如响应内容缓存。一般说来,HttpClient实际上就是一系列特殊的handler或者说策略接口的实现,这些handler(测试接口)负责着处理Http协议的某一方面,比如重定向、认证处理、有关连接持久性和keep alive持续时间的决策。这样就允许用户使用自定义的参数来代替默认配置,实现个性化的功能。
  1. ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy() {  
  2.   
  3.     @Override  
  4.     public long getKeepAliveDuration(  
  5.             HttpResponse response,  
  6.             HttpContext context) {  
  7.         long keepAlive = super.getKeepAliveDuration(response, context);  
  8.         if (keepAlive == -1) {  
  9.             // Keep connections alive 5 seconds if a keep-alive value  
  10.             // has not be explicitly set by the server  
  11.             keepAlive = 5000;  
  12.         }  
  13.         return keepAlive;  
  14.     }  
  15.   
  16. };  
  17. CloseableHttpClient httpclient = HttpClients.custom()  
  18.         .setKeepAliveStrategy(keepAliveStrat)  
  19.         .build();  
ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy() {

    @Override
    public long getKeepAliveDuration(
            HttpResponse response,
            HttpContext context) {
        long keepAlive = super.getKeepAliveDuration(response, context);
        if (keepAlive == -1) {
            // Keep connections alive 5 seconds if a keep-alive value
            // has not be explicitly set by the server
            keepAlive = 5000;
        }
        return keepAlive;
    }

};
CloseableHttpClient httpclient = HttpClients.custom()
        .setKeepAliveStrategy(keepAliveStrat)
        .build();

HTTPCLIENT的线程安全性

HttpClient已经实现了线程安全。因此建议一个实例被多个请求重用。
 

HTTPCLIENT资源分配

当一个CloseableHttpClient的实例不再被使用,并且它的作用范围即将失效,和它相关的连接必须被关闭,关闭方法可以调用CloseableHttpClient的close()方法。
  1. CloseableHttpClient httpclient = HttpClients.createDefault();  
  2. try {  
  3.     <…>  
  4. } finally {  
  5.     httpclient.close();  
  6. }  
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
    <...>
} finally {
    httpclient.close();
}

Http执行上下文

最初,Http被设计成一种无状态的、面向请求-响应的协议。然而,在实际使用中,我们希望能够在一些逻辑相关的请求-响应中,保持状态信息。为了使应用程序可以保持Http的持续状态,HttpClient允许http连接在特定的Http上下文中执行。如果在持续的http请求中使用了同样的上下文,那么这些请求就可以被分配到一个逻辑会话中。HTTP上下文就和一个java.util.Map<String, Object>功能类似。它实际上就是一个任意命名的值的集合。应用程序可以在Http请求执行前填充上下文的值,也可以在请求执行完毕后检查上下文。
HttpContext可以包含任意类型的对象,因此如果在多线程中共享上下文会不安全。建议每个线程都只包含自己的http上下文。
在Http请求执行的过程中,HttpClient会自动添加下面的属性到Http上下文中:
HttpConnection的实例,表示客户端与服务器之间的连接
HttpHost的实例,表示要连接的目标服务器
HttpRoute的实例,表示全部的连接路由
HttpRequest的实例,表示Http请求。在执行上下文中,最终的HttpRequest对象会代表http消息的状态。Http/1.0和Http/1.1都默认使用相对的uri。但是如果使用了非隧道模式的代理服务器,就会使用绝对路径的uri。
HttpResponse的实例,表示Http响应
java.lang.Boolean对象,表示是否请求被成功的发送给目标服务器
RequestConfig对象,表示http request的配置信息
java.util.List<Uri>对象,表示Http响应中的所有重定向地址
可以使用HttpClientContext这个适配器来简化和上下文状态交互的过程。
  1. HttpContext context = <…>  
  2. HttpClientContext clientContext = HttpClientContext.adapt(context);  
  3. HttpHost target = clientContext.getTargetHost();  
  4. HttpRequest request = clientContext.getRequest();  
  5. HttpResponse response = clientContext.getResponse();  
  6. RequestConfig config = clientContext.getRequestConfig();  
HttpContext context = <...>
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpHost target = clientContext.getTargetHost();
HttpRequest request = clientContext.getRequest();
HttpResponse response = clientContext.getResponse();
RequestConfig config = clientContext.getRequestConfig();
同一个逻辑会话中的多个Http请求,应该使用相同的Http上下文来执行,这样就可以自动地在http请求中传递会话上下文和状态信息。
在下面的例子中,我们在开头设置的参数,会被保存在上下文中,并且会应用到后续的http请求中。
  1. CloseableHttpClient httpclient = HttpClients.createDefault();  
  2. RequestConfig requestConfig = RequestConfig.custom()  
  3.         .setSocketTimeout(1000)  
  4.         .setConnectTimeout(1000)  
  5.         .build();  
  6.   
  7. HttpGet httpget1 = new HttpGet(“http://localhost/1”);  
  8. httpget1.setConfig(requestConfig);  
  9. CloseableHttpResponse response1 = httpclient.execute(httpget1, context);  
  10. try {  
  11.     HttpEntity entity1 = response1.getEntity();  
  12. } finally {  
  13.     response1.close();  
  14. }  
  15. HttpGet httpget2 = new HttpGet(“http://localhost/2”);  
  16. CloseableHttpResponse response2 = httpclient.execute(httpget2, context);  
  17. try {  
  18.     HttpEntity entity2 = response2.getEntity();  
  19. } finally {  
  20.     response2.close();  
  21. }  
CloseableHttpClient httpclient = HttpClients.createDefault();
RequestConfig requestConfig = RequestConfig.custom()
        .setSocketTimeout(1000)
        .setConnectTimeout(1000)
        .build();

HttpGet httpget1 = new HttpGet("http://localhost/1");
httpget1.setConfig(requestConfig);
CloseableHttpResponse response1 = httpclient.execute(httpget1, context);
try {
    HttpEntity entity1 = response1.getEntity();
} finally {
    response1.close();
}
HttpGet httpget2 = new HttpGet("http://localhost/2");
CloseableHttpResponse response2 = httpclient.execute(httpget2, context);
try {
    HttpEntity entity2 = response2.getEntity();
} finally {
    response2.close();
}

HTTP协议拦截器

HTTP协议拦截器是一种实现一个特定的方面的HTTP协议的代码程序。通常情况下,协议拦截器会将一个或多个头消息加入到接收或者发送的消息中。协议拦截器也可以操作消息的内容实体—消息内容的压缩/解压缩就是个很好的例子。通常,这是通过使用“装饰”开发模式,一个包装实体类用于装饰原来的实体来实现。一个拦截器可以合并,形成一个逻辑单元。协议拦截器可以通过共享信息协作——比如处理状态——通过HTTP执行上下文。协议拦截器可以使用Http上下文存储一个或者多个连续请求的处理状态。通常,只要拦截器不依赖于一个特定状态的http上下文,那么拦截执行的顺序就无所谓。如果协议拦截器有相互依赖关系,必须以特定的顺序执行,那么它们应该按照特定的顺序加入到协议处理器中。协议处理器必须是线程安全的。类似于servlets,协议拦截器不应该使用实例变量,除非访问这些实例变量是同步的(线程安全的)。
下面是个例子,讲述了本地的上下文时如何在连续请求中记录处理状态的:

  1. CloseableHttpClient httpclient = HttpClients.custom()  
  2.         .addInterceptorLast(new HttpRequestInterceptor() {  
  3.   
  4.             public void process(  
  5.                     final HttpRequest request,  
  6.                     final HttpContext context) throws HttpException, IOException {  
  7.                 AtomicInteger count = (AtomicInteger) context.getAttribute(”count”);  
  8.                 request.addHeader(”Count”, Integer.toString(count.getAndIncrement()));  
  9.             }  
  10.   
  11.         })  
  12.         .build();  
  13.   
  14. AtomicInteger count = new AtomicInteger(1);  
  15. HttpClientContext localContext = HttpClientContext.create();  
  16. localContext.setAttribute(”count”, count);  
  17.   
  18. HttpGet httpget = new HttpGet(”http://localhost/”);  
  19. for (int i = 0; i < 10; i++) {  
  20.     CloseableHttpResponse response = httpclient.execute(httpget, localContext);  
  21.     try {  
  22.         HttpEntity entity = response.getEntity();  
  23.     } finally {  
  24.         response.close();  
  25.     }  
  26. }  
CloseableHttpClient httpclient = HttpClients.custom() 
.addInterceptorLast(new HttpRequestInterceptor() {

        public void process(
                final HttpRequest request,
                final HttpContext context) throws HttpException, IOException {
            AtomicInteger count = (AtomicInteger) context.getAttribute("count");
            request.addHeader("Count", Integer.toString(count.getAndIncrement()));
        }

    })
    .build();

AtomicInteger count = new AtomicInteger(1);
HttpClientContext localContext = HttpClientContext.create();
localContext.setAttribute(“count”, count);

HttpGet httpget = new HttpGet(“http://localhost/“);
for (int i = 0; i < 10; i++) {
CloseableHttpResponse response = httpclient.execute(httpget, localContext);
try {
HttpEntity entity = response.getEntity();
} finally {
response.close();
}
}


异常处理

HttpClient会被抛出两种类型的异常,一种是java.io.IOException,当遇到I/O异常时抛出(socket超时,或者socket被重置);另一种是HttpException,表示Http失败,如Http协议使用不正确。通常认为,I/O错误时不致命、可修复的,而Http协议错误是致命了,不能自动修复的错误。请注意,HttpException如果被重新抛出成IOException的子类ClientProtocolException,就可以让用户在一个catch语句里同时处理I/O错误和协议错误。

HTTP传输安全

Http协议不能满足所有类型的应用场景,我们需要知道这点。Http是个简单的面向协议的请求/响应的协议,当初它被设计用来支持静态或者动态生成的内容检索,之前从来没有人想过让它支持事务性操作。例如,Http服务器成功接收、处理请求后,生成响应消息,并且把状态码发送给客户端,这个过程是Http协议应该保证的。但是,如果客户端由于读取超时、取消请求或者系统崩溃导致接收响应失败,服务器不会回滚这一事务。如果客户端重新发送这个请求,服务器就会重复的解析、执行这个事务。在一些情况下,这会导致应用程序的数据损坏和应用程序的状态不一致。即使Http当初设计是不支持事务操作,但是它仍旧可以作为传输协议为某些关键程序提供服务。为了保证Http传输层的安全性,系统必须保证应用层上的http方法的幂等性。

方法的幂等性

HTTP/1.1规范中是这样定义幂等方法的,[Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request]。用其他话来说,应用程序需要做好准备,处理同一方法多次执行造成的影响。添加一个具有唯一性的id就能避免重复执行同一个逻辑请求,问题解决。请知晓,这个问题不只是HttpClient才会有,基于浏览器的应用程序也会遇到Http方法不幂等的问题。HttpClient默认把非实体方法get、head方法看做幂等方法,把实体方法post、put方法看做非幂等方法。

异常自动修复

默认情况下,HttpClient会尝试自动修复I/O异常。这种自动修复仅限于修复几个公认安全的异常。
HttpClient不会尝试修复任何逻辑或者http协议错误(即从HttpException衍生出来的异常)。
HttpClient会自动再次发送幂等的方法(如果首次执行失败)。
HttpClient会自动再次发送遇到transport异常的方法,前提是Http请求仍旧保持着连接(例如http请求没有全部发送给目标服务器,HttpClient会再次尝试发送)。

请求重试HANDLER

如果要自定义异常处理机制,我们需要实现HttpRequestRetryHandler接口。请注意,可以使用StandardHttpRequestRetryHandler替代默认的接口以便使那些在 RFC-2616定义的幂等性的请求方法安全的自动重试:GET, HEAD, PUT, DELETE, OPTIONS, TRACE。
  1. HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {  
  2.   
  3.     public boolean retryRequest(  
  4.             IOException exception,  
  5.             int executionCount,  
  6.             HttpContext context) {  
  7.         if (executionCount >= 5) {  
  8.             // Do not retry if over max retry count  
  9.             return false;  
  10.         }  
  11.         if (exception instanceof InterruptedIOException) {  
  12.             // Timeout  
  13.             return false;  
  14.         }  
  15.         if (exception instanceof UnknownHostException) {  
  16.             // Unknown host  
  17.             return false;  
  18.         }  
  19.         if (exception instanceof ConnectTimeoutException) {  
  20.             // Connection refused  
  21.             return false;  
  22.         }  
  23.         if (exception instanceof SSLException) {  
  24.             // SSL handshake exception  
  25.             return false;  
  26.         }  
  27.         HttpClientContext clientContext = HttpClientContext.adapt(context);  
  28.         HttpRequest request = clientContext.getRequest();  
  29.         boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);  
  30.         if (idempotent) {  
  31.             // Retry if the request is considered idempotent  
  32.             return true;  
  33.         }  
  34.         return false;  
  35.     }  
  36.   
  37. };  
  38. CloseableHttpClient httpclient = HttpClients.custom()  
  39.         .setRetryHandler(myRetryHandler)  
  40.         .build();  
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

    public boolean retryRequest(
            IOException exception,
            int executionCount,
            HttpContext context) {
        if (executionCount >= 5) {
            // Do not retry if over max retry count
            return false;
        }
        if (exception instanceof InterruptedIOException) {
            // Timeout
            return false;
        }
        if (exception instanceof UnknownHostException) {
            // Unknown host
            return false;
        }
        if (exception instanceof ConnectTimeoutException) {
            // Connection refused
            return false;
        }
        if (exception instanceof SSLException) {
            // SSL handshake exception
            return false;
        }
        HttpClientContext clientContext = HttpClientContext.adapt(context);
        HttpRequest request = clientContext.getRequest();
        boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
        if (idempotent) {
            // Retry if the request is considered idempotent
            return true;
        }
        return false;
    }

};
CloseableHttpClient httpclient = HttpClients.custom()
        .setRetryHandler(myRetryHandler)
        .build();

中断请求

有时候由于目标服务器负载过高或者客户端目前有太多请求积压,http请求不能在指定时间内执行完毕。这时候终止这个请求,释放阻塞I/O的进程,就显得很必要。通过HttpClient执行的Http请求,在任何状态下都能通过调用HttpUriRequest的abort()方法来终止。这个方法是线程安全的,并且能在任何线程中调用。当Http请求被终止了,本线程(即使现在正在阻塞I/O)也会通过抛出一个InterruptedIOException异常,来释放资源。

重定向处理

HttpClient会自动处理所有类型的重定向,除了那些Http规范明确禁止的重定向。See Other (status code 303) redirects on POST and PUT requests are converted to GET requests as required by the HTTP specification. 可以使用自定义的重定向策略来放松Http规范对Post方法重定向的限制。
  1. LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();  
  2. CloseableHttpClient httpclient = HttpClients.custom()  
  3.         .setRedirectStrategy(redirectStrategy)  
  4.         .build();  
LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
CloseableHttpClient httpclient = HttpClients.custom()
        .setRedirectStrategy(redirectStrategy)
        .build();
HttpClient在请求执行过程中,经常需要重写请求的消息。 HTTP/1.0和HTTP/1.1都默认使用相对的uri路径。同样,原始的请求可能会被者多次的重定向。最终绝对路径可以使用原始的请求和上下文来构建。URIUtils#resolve可以用于构建绝对路径,产生最终的请求。这个方法包含了最后一个分片标识符或者原始请求。
  1. CloseableHttpClient httpclient = HttpClients.createDefault();  
  2. HttpClientContext context = HttpClientContext.create();  
  3. HttpGet httpget = new HttpGet(“http://localhost:8080/”);  
  4. CloseableHttpResponse response = httpclient.execute(httpget, context);  
  5. try {  
  6.     HttpHost target = context.getTargetHost();  
  7.     List<URI> redirectLocations = context.getRedirectLocations();  
  8.     URI location = URIUtils.resolve(httpget.getURI(), target, redirectLocations);  
  9.     System.out.println(”Final HTTP location: ” + location.toASCIIString());  
  10.     // Expected to be an absolute URI  
  11. } finally {  
  12.     response.close();  
  13. }  
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
HttpGet httpget = new HttpGet("http://localhost:8080/");
CloseableHttpResponse response = httpclient.execute(httpget, context);
try {
    HttpHost target = context.getTargetHost();
    List<URI> redirectLocations = context.getRedirectLocations();
    URI location = URIUtils.resolve(httpget.getURI(), target, redirectLocations);
    System.out.println("Final HTTP location: " + location.toASCIIString());
    // Expected to be an absolute URI
} finally {
    response.close();
}

httpclient4.5 的 httpclient对象是可以作为单例复用的吗? Apache HttpClient 4.5 的 `HttpClient` 对象可以作为单例复用,且这是官方推荐的最佳实践 阅读详情

相关推荐

Apache HttpClient 4和5访问没有有效证书的HTTPS

本文将展示如何配置Apache HttpClient 4和5以支持“接受所有”SSL。目标很简单——访问没有有效证书的HTTPS URL。

疯一样的码农 1214

HttpClient4.5详解

1.HttpClient简介 HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 Http

木槿落空樱桃忽而 % 1m 4344

Apache HttpClient 4.5实现https

没什么,就是记录个代码。 全部信任的 import org.apache.commons.collections.MapUtils; import org.apache.http.*; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPos...

编故事的逗老师的专栏 1804

【HttpClient】HttpClient4.5基础教程

一、前言 1、说明 HttpClient是一个目前最常用的用于模拟客户端发送http请求的工具,可用于接口自动化测试或者爬虫或者在项目中加入获取其他网站数据等; 支持目前所有的请求方式,如put,post,get,delete等; 2、maven依赖添加 maven依赖如下: &amp;amp;amp;lt;dependency&amp;amp;amp;gt; &amp;amp;amp;lt;groupId&amp;amp;amp;gt;org.apache.ht

df0128的专栏 1万+

HTTPClient 4.5:必备Jar包及源码解析

在当今的网络时代,HTTPClient作为一款广泛使用的网络通信客户端库,对于Web开发者而言可谓是不可或缺的工具。本章节将简要介绍HTTPClient的基础知识及其在应用开发中的重要性。HTTPClient是一个开源的Java HTTP客户端库,它提供了访问Web服务器的简易方式。通过它,开发者可以构建HTTP请求、发送请求并接收响应,这些操作都封装在易于理解和使用的API中。超文本传输协议(HTTP)是互联网上应用最为广泛的一种网络协议。

weixin_32445049的博客 929

httpclient4.5 jar包

httpclient4.5 所需jar包,直接导入的项目即可,方便省心

Apache HttpClient5 介绍及快速入门示例

Apache HttpClient5 介绍及快速入门示例

jackiendsc的博客 3091

基于人脸识别的驾驶员疲劳检测方法研究

摘 要交通安全问题愈发严重,疲劳驾驶已是造成交通事故的主要因素之一。为减少因疲劳驾驶造成的交通事故,本文设计了一种基于图像处理技术的疲劳驾驶监测系统,该系统结合了肤色模型、灰度积分投影技术以及PERCLOS方法,旨在通过实时视频图像分析准确检测驾驶员的疲劳状态。首先,系统通过肤色模型从图像中有效提取人脸区域,并在此基础上利用Haar级联分类器进行人脸检测,确保在人脸角度变化或部分遮挡的情况下依然能够实现高效识别。接着,灰度积分投影技术被应用于眼部定位,通过分析眼睛区域的灰度变化,精确确定眼睛的上下边界,从

carrott0617的博客 1005

HttpClient4.5 入门

引言 本文主要记录如何初始化HttpClient4.5.x和入门使用. 参考官方文档 http://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/html/ 1. 构建HttpClient 1.1 构建前准备 在构建之前, 先大致了解一下HttpClient类 HttpClient子类 DecompressingHttpClient: HttpClient装饰器类, 支持解压逻辑. AutoRetryHttpClient: Http

更新博客 907

中文顶刊《会计研究》文本分析技术最新进展总结盘点

会计研究》是由中华人民共和国财政部主管、中国会计学会主办的国家一级学术期刊,为会计领域中文顶级期刊。随着大数据技术的日益成熟, 社交网络类文本 、上市公司披露类文本、媒体报道类文本、 其他类文本 、网络搜索数据、P2P 网络借贷文 本与分析师报告等文本数据逐渐成为财务会计的研究素材。

qq_52891550的博客 2894

风力摆控制系统 PCB 设计 3 要点:STM32+MPU6050+空心杯电机驱动一体化

本文详细解析了风力摆控制系统PCB设计的3大核心要点,重点介绍STM32主控、MPU6050姿态传感器与空心杯电机驱动的一体化方案。通过系统架构设计、PCB布局布线技巧以及噪声抑制方案,帮助参赛者在电子设计竞赛中构建高精度、高稳定性的风力摆控制系统,提升竞赛作品性能。

weixin_30363285的博客 363

基于HttpClient4.5实现网络爬虫

这里做一个简短的说明,之前在博客《基于HttpClient实现网络爬虫~以百度新闻为例》介绍了如何基于HttpClient3.0来模拟浏览器请求,但从4.0版本之后,Apache就对这个包做了很大的改动,这里就针对目前比较新的版本4.5再来介绍下如何模拟浏览器的请求

小鸡慢慢的专栏 7333

微信小程序 - 最新详细实现模板消息订阅通知功能,给用户微信发送“服务通知“模板消息并点击进入跳转到小程序页面路由,订阅消息通知详细后台申请流程及示例代码,解决授权申请弹框被拒绝后无法调起、常见报错!

微信小程序,vue2,vue3,模板消息,订阅通知,服务通知,小程序模板通知,订阅微信模板消息功能,唤起模板消息订阅弹框并发送服务通知,消息订阅与模板消息发送,一次性订阅,长期永久订阅,申请模板id,详细示例代码教程,配置流程,消息模板,模板ID,用户收不到消息,订阅了通知但微信不来服务通知,报错,小程序平台模板消息订阅功能,唤起订阅模板消息弹框,订阅模板消息发送服务通知功能,如何做模板消息订阅,一直收不到通知,用户通过弹窗订阅,订阅消息,无法打开申请授权弹框,用户拒绝/关闭后,如何引导用户再开启,拒绝后怎

🏆 前端领域优质创作者 5331

httpclient4.5.3 使用

我这里是使用maven来构建项目,用普通工程的请下载相关的包后加入buildpath 。 新建一个maven工程,这里我只是简单的写了两种请求 这里选择勾选建立一个简单工程 红色的地方可以根据需求选择,点击完成。 org.apache.httpcomponents httpclient 4.5.3 log4j

u012410349的博客 7675

基于MATLAB的PDT DMR物理层仿真

PDT DMR物理层仿真的目标是评估系统的误码率(Bit Error Rate,BER),以及验证和优化各种调制方案、编码方案和信道模型。下面将介绍如何进行PDT DMR物理层的仿真,并提供相应的MATLAB源代码。通过上述步骤,我们可以进行基于MATLAB的PDT DMR物理层仿真,并评估系统的性能。根据实际需求,我们可以修改仿真参数和添加更复杂的信道模型,以更全面地评估系统性能。最后,我们可以将仿真结果进行可视化和分析。首先,我们需要设置仿真的参数,包括调制方案、编码方案、信道模型和信噪比等。

TechPulseZ的博客 459

【服务器电源架构与关键技术发展趋势】AI数据中心迅猛发展,服务器电源如何演变?

功率级跃升:机柜功率从 100kW 向 1MW 级发展,供电架构采用 HVDC + 固态变压器(SST),省去传统 UPS、PFC 环节; 母线电压升级:从 48V 向 400V→800V 演进,配套 AI 电弧检测、智能运维解决高压安全与维护难题; 能效(PUE)提升:目标 PUE<1.3,通过液冷 CDU 替代传统风冷,可将 PUE 降至 1.16(传统 AI 集群 PUE 达 1.6); 拓扑控制复杂化:功率拓扑从单相→三相、单级→多交错结构,适配高功率需求; 安全维度扩展:新增网络安全防护需求。

昔时扬尘处 1451

HttpClient4.5 简单入门

HttpClient4.5 简单入门 博客分类: httpclient httpclientgetposthttp  一、所需要的jar包    httpclient-4.5.jar    httpcore-4.4.1.jar    httpmime-4.5.jar 二、实例 Java代码   package cn.tzz.apache.ht

zkwniky的博客 374

软件需求规格说明书(SRS)标准模板

《软件需求规格说明书(SRS)框架解析》摘要: 本文档系统阐述了SRS的标准结构,包含7大核心部分:1)引言(目的、背景和术语);2)总体描述(产品定位与用户特征);3)功能需求(模块化功能说明);4)非功能需求(性能、安全等指标);5)接口需求(用户/硬件/软件接口);6)其他技术要求;7)附录(图表与参考资料)。重点突出了功能需求模块的标准化描述模板(FR-01),以及安全需求中的HTTPS通信、SHA-256加密等关键指标。该框架为软件开发提供了明确的需求基准,涵盖从业务背景到技术实现的完整链条,是确

moton2017的博客 2894

HttpClient4.5 简单入门实例(一)

一、所需要的jar包    httpclient-4.5.jar    httpcore-4.4.1.jar    httpmime-4.5.jar 二、实例 package cn.tzz.apache.httpclient; import java.io.File; import java.io.IOException; import java.net.URL; import j...

tanksyg的专栏 1496

1、掌握 Microsoft Dynamics 365 Business Central 开发全解析

本文全面解析了Microsoft Dynamics 365 Business Central的开发全流程,涵盖开发环境搭建、AL语言扩展开发、定制解决方案实现、高级开发技术、文件与报表处理、打印功能、调试与性能优化、API使用、Azure和Power Platform集成、DevOps实践以及生成式AI应用。同时探讨了开发工具技巧、常见问题解决、开发流程优化、团队协作要点及未来技术趋势,帮助开发者系统掌握Business Central开发核心技能,提升企业级应用开发效率与质量。

food6的博客 112

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

从HttpClient4升级到HttpClient5,坑坑坑

我最近要把HttpClient4升级到HttpClient5,在升级的过程中,发现许多 API 已删除了,并且也没有找到非常合适的文档可用于全面了解升级方案。目前网上的博客或者帖子大部分都是与httpcomponents4.x 相关的回答,但这些 API 在HttpClient5里,已经被删除或者修改了。我把我目前用到的或者查询到的备选方案先写出来。如果有高手,请指正这些中的问题。

pbdatax的博客 7495

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Spring Cloud OpenFeign4不支持Apache HttpClient4,推荐使用OkHttpClient或Apache HttpClient 5

Spring Cloud OpenFeign4 使用HTTP客户端配置说明

qq_38662415的博客 2398

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

基于 HttpClient 4.5 的 HttpClientUtils

欢迎关注微信公众号:PM实验室 我编写工具类所参考的文档 pache HttpClient: http://hc.apache.org/httpcomponents-client-ga/index.html 中文翻译教程: https://www.yiibai.com/apache_httpclient stackoverflow 关于SSL的讨论: https://stackoverfl...

野指针er 1525

理解并使用.NET 4.5中的HttpClient

理解并使用.NET 4.5中的HttpClient 时间2016-01-27 栏目系统网络 背景 在平时工作中我偶尔会写一些脚本监控HTTP接口的健康状况,基本上都是发送HTTP GET或HTTP POST请求,然后检测响应内容。但一直用的是WebClient和HttpWebRequest,虽然用它们也能进行异步请求(可参考我分享的代码:C#异步GET的3个例子),但总感觉那...

MaFeng 7091

Apache HttpClient 4.5设置超时时间

Apache HttpClient 老版本的设置超时方式在4.3之后就不能用了,新的方式是这样的: `setConnectTimeout` :设置连接超时时间,单位毫秒。 `setConnectionRequestTimeout` :设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。 `setSocketTimeout` :请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次

一只没有脚的鸟 7795

httpclient4.5 的一些细节

httpclient4.5 的一些细节 lient是Apache下的一个用于执行http网络访问的一个工具包。 大致流程:新建一个httpclient对象->新建一个httpRequest对象->用httpclient去执行->得到一个response->通过解析这个response来获取自己所需要的信息。   一、新建httpClient对象: 在h

dotedy的博客 1016
上一篇: spring-data-redis 操作
下一篇: httpclient UrlEncodedFormEntity
光与热
博客等级 码龄11年 55粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值