仅自己使用,原文:http://hc.apache.org/httpcomponents-client-ga/tutorial/html/
The most essential function of HttpClient is to execute HTTP methods.
HTTP客户端最常见的功能是执行Http方法Quite naturally, the main entry point of the HttpClient API is the HttpClient interface that defines the contract described above.
Here is an example of request execution process in its simplest form:
理所当然的,HTTP客户端的最主要的入口是上面定义的约定。这里是一个请求执行的描述:All HTTP requests have a request line consisting a method name, a request URI and an HTTP protocol version.
HttpClient supports out of the box all HTTP methods defined in the HTTP/1.1 specification: GET, HEAD, POST, PUT, DELETE, TRACE and OPTIONS. There is a specific class for each method type.: HttpGet, HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace, and HttpOptions.
The Request-URI is a Uniform Resource Identifier that identifies the resource upon which to apply the request. HTTP request URIs consist of a protocol scheme, host name, optional port, resource path, optional query, and optional fragment.
所有的HTTP请求有一个请求行包含了方法名,一个请求URI和HTTP协议版本stdout >
http:///search?q=httpclient&btnG=Google+Search&aq=f&oq=
HTTP response is a message sent by the server back to the client after having
received and interpreted a request message. The first line of that message consists
of the protocol version followed by a numeric status code and its associated textual
phrase.
HTTP responsehi一个服务器返回的响应。第一行包含了协议版本,数字状态码及相关的文本短语。
An HTTP message can contain a number of headers describing properties of the message such as the content length, content type and so on. HttpClient provides methods to retrieve, add, remove and enumerate headers.
一个HTTP信息包含了大量的头信息描述消息的熟悉,如长度,内容类型等。HTTP客户端提供查询/增加/删除和列举头信息。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);
Header h2 = response.getLastHeader("Set-Cookie");
System.out.println(h2);
Header[] hs = response.getHeaders("Set-Cookie");
System.out.println(hs.length);
stdout >
Set-Cookie: c1=a; path=/; domain=localhost Set-Cookie: c2=b; path="/", c3=c; domain="localhost" 2The most efficient way to obtain all headers of a given type is by using the HeaderIterator interface.
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]);
}
}
stdout >
c1 = a path=/ domain=localhost c2 = b path=/ c3 = c domain=localhost
HTTP messages can carry a content entity associated with the request or response.
Entities can be found in some requests and in some responses, as they are optional.
Requests that use entities are referred to as entity enclosing requests. The HTTP
specification defines two entity enclosing request methods: POST and PUT. Responses are usually expected to enclose a content
entity. There are exceptions to this rule such as responses to HEAD method and 204 No Content, 304 Not Modified, 205 Reset Content responses.
HTTP消息能够携带一个与请求或相应相关联的内容提。实体能够在一些请求和相应中找到,他们是可选的。使用实体的请求被称为实体封装请求。HTTP规范定义了两种实体封装方法:POST和PUT。响应通常期望是一个封装的内容体。也有例外情况:比如响应HEAD方法和204没有内容,304无修改,205重置内容响应。
HttpClient distinguishes three kinds of entities, depending on where their content
originates:
HTTP客户端区分三种实体,取决于内容来源:
streamed: The content is received from a stream, or generated on the fly. In particular, this category includes entities being received from HTTP responses. Streamed entities are generally not repeatable.
self-contained: The content is in memory or obtained by means that are independent from a connection or other entity. Self-contained entities are generally repeatable. This type of entities will be mostly used for entity enclosing HTTP requests.
wrapping: The content is obtained from another entity.
流:这个种内容来自于一个流或者在运行中产生。尤其,这种类型包括从HTTP响应中接受到的实体。流类型的实体通常不会重复。
自包含类型:这种内容通常位于内存或者通过一个连接或者别的实体获得。自包含实体通常是可以重复的。这种类型的实体大多用于实体封装的HTTP请求。
封装:这种内容来自于另一个实体。
This distinction is important for connection management when streaming out content
from an HTTP response. For request entities that are created by an application and
only sent using HttpClient, the difference between streamed and self-contained is of
little importance. In that case, it is suggested to consider non-repeatable entities
as streamed, and those that are repeatable as self-contained.
An entity can be repeatable, meaning its content can be read more than once.
This is only possible with self contained entities (like ByteArrayEntity or StringEntity)
一个实体如果是可重复的,意味着实体内容可以被多次读取。只有自包含的实体是可重复的。
Since an entity can represent both binary and character content, it has
support for character encodings (to support the latter, ie. character
content).
因为一个实体既能表示二进制的实体也能表示字符内容的实体,也支持字符编码。
The entity is created when executing a request with enclosed content or when
the request was successful and the response body is used to send the result back
to the client.
实体在当请求被执行时或者响应体返回时被创建。
To read the content from the entity, one can either retrieve the input stream
via the HttpEntity#getContent() method, which returns
an java.io.InputStream, or one can supply an output
stream to the HttpEntity#writeTo(OutputStream) method,
which will return once all content has been written to the given stream.
为了从实体中读取内容,xxxxxx。
When the entity has been received with an incoming message, the methods HttpEntity#getContentType() and HttpEntity#getContentLength() methods can be used
for reading the common metadata such as Content-Type and Content-Length headers (if they are available). Since the Content-Type header can contain a character encoding for
text mime-types like text/plain or text/html, the HttpEntity#getContentEncoding() method is used to
read this information. If the headers aren't available, a length of -1 will be
returned, and NULL for the content type. If the Content-Type header is available, a Header object will be
returned.
当实体从消息中取出的时候,getContentType和getContentLength方法能够用于读取xxx。由于getContentType能够为text/plain or text/html包含一个字符编码。getContentEncoding用于读取这个信息。如果消息头不可用,则返回长度-1.内容类型为null.如果内容类型头信息可用,将返回一个消息头对象。
When creating an entity for a outgoing message, this meta data has to be supplied by the creator of the entity.
In order to ensure proper release of system resources one must close either the content stream associated with the entity or the response itself
为了保证合理释放系统资源我们必须关闭与实体相关的内容流或者响应本身相关联的内容流The difference between closing the content stream and closing the response is that the former will attempt to keep the underlying connection alive by consuming the entity content while the latter immediately shuts down and discards the connection.
Please note that the HttpEntity#writeTo(OutputStream) method is also required to ensure proper release of system resources once the entity has been fully written out. If this method obtains an instance of java.io.InputStream by calling HttpEntity#getContent(), it is also expected to close the stream in a finally clause.
When working with streaming entities, one can use the EntityUtils#consume(HttpEntity) method to ensure that the entity content has been fully consumed and the underlying stream has been closed.
There can be situations, however, when only a small portion of the entire response content needs to be retrieved and the performance penalty for consuming the remaining content and making the connection reusable is too high, in which case one can terminate the content stream by closing the response.
关闭内容流和关闭相应不同的地方时前者试图聪哥消耗实体内容保持底层连接,而后者直接关闭并且丢弃连接。
The recommended way to consume the content of an entity is by using its HttpEntity#getContent() or HttpEntity#writeTo(OutputStream) methods. HttpClient
also comes with the EntityUtils class, which exposes several
static methods to more easily read the content or information from an entity.
Instead of reading the java.io.InputStream directly, one can
retrieve the whole content body in a string / byte array by using the methods from
this class. However, the use of EntityUtils is
strongly discouraged unless the response entities originate from a trusted HTTP
server and are known to be of limited length.
推荐使用getContent方法或者writeTo方法区消耗实体内容。HTTP客户端还配备了EntityUtils类,提供了几个方便从实体中读取内容和消息的静态方法。我们不需要直接使用InputStream,就能够用这个类从字符串或者字节数组中直接获取整个内容。但是强烈不建议使用EntityUtils,除非响应实体来自于一个可以信任的HTTP服务器并且知道长度限制。
HttpClient provides several classes that can be used to efficiently stream out
content throught HTTP connections. Instances of those classes can be associated with
entity enclosing requests such as POST and PUT in order to enclose entity content into outgoing HTTP requests. HttpClient provides
several classes for most common data containers such as string, byte array, input
stream, and file: StringEntity, ByteArrayEntity, InputStreamEntity, and FileEntity.
Http客户端提供几个能够高效的从HTTP连接中读取内容的类。这些类的实体与封装实体请求POST和PUT相关联,以便实体内容通过HTTP请求传输出去。HTTP客户端提供几个常见数据容器的类,例如:.....。
Please note InputStreamEntity is not repeatable, because it
can only read from the underlying data stream once. Generally it is recommended to
implement a custom HttpEntity class which is
self-contained instead of using the generic InputStreamEntity. FileEntity can be a good starting point.
请注意InputStreamEntity是不可重复的,因为他只能从底层数据流读取一次。通常推荐实现一个自定义的HttpEntity类
Many applications need to simulate the process of submitting an
HTML form, for instance, in order to log in to a web application or submit input
data. HttpClient provides the entity class UrlEncodedFormEntity to facilitate the
process.
许多应用需要模拟处理HTML表单,例如为了登陆一个web应用或者提交录入的数据。HTTP客户端提供了实体类UrlEncodedFormEntity帮助处理。
Generally it is recommended to let HttpClient choose the most appropriate transfer encoding based on the properties of the HTTP message being transferred. It is possible, however, to inform HttpClient that chunk coding is preferred by setting HttpEntity#setChunked() to true. Please note that HttpClient will use this flag as a hint only. This value will be ignored when using HTTP protocol versions that do not support chunk coding, such as HTTP/1.0.
通常建议让HTTP客户端选择根据HTTP消息属性最适合的传输编码。但是,通过setChunked设置为true通知HTTP优先使用chunk的编码。请注意:HTTP客户端只是使用这个标识作为一个示意。如果协议版本不支持,如HTTP1.0,则这个值会被忽略。
The simplest and the most convenient way to handle responses is by using
the ResponseHandler interface, which includes
the handleResponse(HttpResponse response) method.
This method completely
relieves the user from having to worry about connection management. When using a ResponseHandler, HttpClient will automatically
take care of ensuring release of the connection back to the connection manager
regardless whether the request execution succeeds or causes an exception.
处理相应最简单最方便的方式是使用ResponseHandler接口,有一个handleResponse方法。这个方法完全消除了用户对连接管理的担心。当使用一个ResponseHandler时,HTTP客户端会自己把连接还给连接管理器而忽略请求是否执行成功。
HttpClient interface represents the most essential
contract for HTTP request execution. It imposes no restrictions or particular details on
the request execution process and leaves the specifics of connection management, state
management, authentication and redirect handling up to individual implementations. This
should make it easier to decorate the interface with additional functionality such as
response content caching.
HTTP客户端接口展示了最基本的HTTP请求执行规范。他没有限定请求执行的具体的细节,把连接管理,状态管理,鉴权和重定向处理的细节留给了个人实现。这样就很容易去给接口加一些额外功能,例如响应缓存。
Generally HttpClient implementations act as a facade
to a number of special purpose handler or strategy interface implementations
responsible for handling of a particular aspect of the HTTP protocol such as redirect
or authentication handling or making decision about connection persistence and keep
alive duration. This enables the users to selectively replace default implementation
of those aspects with custom, application specific ones.
通常HTTP客户端充当一个处理大量具体用途(负责处理HTTP协议的某个具体方面,比如重定向、鉴权处理、连接持久化、保活时间)的处理程序的外壳。这使用户能够有选择的个性化的去替换某些方面的实现,为应用做定制。
HttpClient implementations are expected to be
thread safe. It is recommended that the same instance of this class is reused for
multiple request executions.
HttpClient实现是线程安全的。推荐这个类的实例被多线程的请求重复使用。
When an instance CloseableHttpClient is no longer needed
and is about to go out of scope the connection manager associated with it must
be shut down by calling the CloseableHttpClient#close() method.
当一个CloseableHttpClient实例没用了,或者不再用连接管理器管理了,必须调用close方式关闭他。
Originally HTTP has been designed as a stateless, response-request oriented protocol.
However, real world applications often need to be able to persist state information
through several logically related request-response exchanges. In order to enable
applications to maintain a processing state HttpClient allows HTTP requests to be
executed within a particular execution context, referred to as HTTP context. Multiple
logically related requests can participate in a logical session if the same context is
reused between consecutive requests. HTTP context functions similarly to
a java.util.Map
原始的HTTP是无状态的。但是现实应用需要通过持久化状态信息。为了让应用维护一个可处理的状态,HTTP客户端运行请求带上上下文,作为HTTP的上下文。多个逻辑相关的请求可以参与到一个逻辑session如果在持续的请求中上下文相同。HTTP上下文函数有点像java.util.Map
HttpContext can contain arbitrary objects and
therefore may be unsafe to share between multiple threads. It is recommended that
each thread of execution maintains its own context.
HttpContext能包含任意对象因此如果多线程共享是不安全的,推荐每个线程维护自己的上下文。
In the course of HTTP request execution HttpClient adds the following attributes to
the execution context:
在执行请求的过程HTTP客户端增加了下列属性执行上下文
HttpConnection instance representing the actual connection to the target server.代表和服务器的实际连接
HttpHost instance representing the connection target.代表连接目标(服务器)
HttpRoute instance representing the complete connection route。代表完整的连接路由
HttpRequest instance representing the actual HTTP request. The final HttpRequest object in the execution context always represents the state of the message exactly as it was sent to the target server. Per default HTTP/1.0 and HTTP/1.1 use relative request URIs. However if the request is sent via a proxy in a non-tunneling mode then the URI will be absolute.代表一个实际的HTTP请求,最终的在上下文中执行的请求对象代表信息状态xxxx。前面默认的1.0 1.1协议使用相对请求URI。但是如果请求是通过一个无隧道代理模式,则是用绝对URI。
HttpResponse instance representing the actual HTTP response.
java.lang.Boolean object representing the flag indicating whether the actual request has been fully transmitted to the connection target.表示请求是不是完全传递给了目标主机。
RequestConfig object representing the actual request configuation.
java.util.List
One can use HttpClientContext adaptor class to simplify
interractions with the context state.
我们可以使用HttpClientContext适配器简化和上下文状态的交互。??????
Multiple request sequences that represent a logically related session should be executed with the same HttpContext instance to ensure automatic propagation of conversation context and state information between requests.
In the following example the request configuration set by the initial request will be
kept in the execution context and get propagated to the consecutive requests sharing
the same context.
同一个逻辑对话的session请求应该被相同的Http上下文执行,确保会话上下文和状态信息在请求中自动切换。
下面的例子中初始化的请求配置会在执行上下文中中保持,并且在连续的请求中共享相同的上下文。
HttpClient can throw two types of exceptions: java.io.IOException in case of an I/O failure such as
socket timeout or an socket reset and HttpException that
signals an HTTP failure such as a violation of the HTTP protocol. Usually I/O errors are
considered non-fatal and recoverable, whereas HTTP protocol errors are considered fatal
and cannot be automatically recovered from.
HttpClient能够抛出两种类型的异常:IOException/HttpException。
It is important to understand that the HTTP protocol is not well suited to all types of applications. HTTP is a simple request/response oriented protocol which was initially designed to support static or dynamically generated content retrieval. It has never been intended to support transactional operations. For instance, the HTTP server will consider its part of the contract fulfilled if it succeeds in receiving and processing the request, generating a response and sending a status code back to the client. The server will make no attempt to roll back the transaction if the client fails to receive the response in its entirety due to a read timeout, a request cancellation or a system crash. If the client decides to retry the same request, the server will inevitably end up executing the same transaction more than once. In some cases this may lead to application data corruption or inconsistent application state.
Even though HTTP has never been designed to support transactional processing, it
can still be used as a transport protocol for mission critical applications provided
certain conditions are met. To ensure HTTP transport layer safety the system must
ensure the idempotency of HTTP methods on the application layer.
认识到HTTP协议并不适合所有应用,是非常重要的。HTTP是一个简单的面向请求/相应的协议,最初设计是为了支持静态/动态的检索内容。从来没有打算支持事务操作。例如,HTTP服务xxxxx
尽管HTTP从来不是为了支持事务处理而设计,xxxx。
HTTP/1.1 specification defines an idempotent method as
[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]
In other words the application ought to ensure that it is prepared to deal with
the implications of multiple execution of the same method. This can be achieved, for
instance, by providing a unique transaction id and by other means of avoiding
execution of the same logical operation.
换而言之,应用应该能够确保考虑到用相同的方法处理多个请求。例如可以通过提供一个简单的事务id和其他手段避免执行相同的逻辑操作。
Please note that this problem is not specific to HttpClient. Browser based applications are subject to exactly the same issues related to HTTP methods non-idempotency.
HttpClient assumes non-entity enclosing methods such as GET and HEAD to be idempotent and entity enclosing methods such as POST and PUT to be not.
要注意的是:不仅仅HTTP客户会碰到这个问题,基于浏览器的应用也会受到同样的与HTTP方法非等幂的问题。
HTTP客户端会假定非实体封装方法如GET/HEAD方法是非等幂的,而实体封装方法例如POST和PUT不是。
By default HttpClient attempts to automatically recover from I/O exceptions. The
default auto-recovery mechanism is limited to just a few exceptions that are known
to be safe.
默认HTTP客户端尝试自动的回复IO异常。xxxxx
HttpClient will make no attempt to recover from any logical or HTTP protocol errors (those derived from HttpException class).
HttpClient will automatically retry those methods that are assumed to be idempotent.
HttpClient will automatically retry those methods that fail with a transport exception while the HTTP request is still being transmitted to the target server (i.e. the request has not been fully transmitted to the server).
In order to enable a custom exception recovery mechanism one should provide an
implementation of the HttpRequestRetryHandler interface.
为了能够提供恢复自定义异常,我们应该提供一个HttpRequestRetryHandler接口的实现类。
In some situations HTTP request execution fails to complete within the expected time frame due to high load on the target server or too many concurrent requests issued on the client side. In such cases it may be necessary to terminate the request prematurely and unblock the execution thread blocked in a I/O operation. HTTP requests being executed by HttpClient can be aborted at any stage of execution by invoking HttpUriRequest#abort() method. This method is thread-safe and can be called from any thread. When an HTTP request is aborted its execution thread - even if currently blocked in an I/O operation - is guaranteed to unblock by throwing a InterruptedIOException
有时候HTTP请求会在期望的时间内无法完成,因为目标服务的高负荷或者客户端有太多的并发请求。这时,可能需要去过早的中断请求和解锁被IO操作阻塞的线程。HttpClient能够用HttpUriRequest#abort()方法在任何执行阶段丢弃HTTP请求。这个方法是县城安全的,并且可以被任何线程调用。当一个请求被丢弃,他的执行线程应该保证解锁并抛出一个InterruptedIOException异常。
The HttpParams interface allows for a great deal of
flexibility in handling configuration of components. Most importantly, new
parameters can be introduced without affecting binary compatibility with older
versions. However, HttpParams also has a certain
disadvantage compared to regular Java beans: HttpParams cannot be assembled using a DI
framework. To mitigate the limitation, HttpClient includes a number of bean classes
that can used in order to initialize HttpParams objects using standard Java bean conventions.
HTTP 参数beans接口允许灵活处理大量组件配置。最重要的是新组件能够被引入,而且不影响与旧版本二进制文件的兼容性????但是HttpParams与普通Java Bean相比也有一个明显的缺点:HttpParams不能用DI框架组装。为了减少限制,HTTP客户端使用了大量bean为了能够用标准的Java规范初始化HttpParams对象。
These are parameters that can impact the process of request execution:
CoreProtocolPNames.PROTOCOL_VERSION='http.protocol.version': defines HTTP protocol version used if not set explicitly on the request object. This parameter expects a value of type ProtocolVersion. If this parameter is not set HTTP/1.1 will be used.
CoreProtocolPNames.HTTP_ELEMENT_CHARSET='http.protocol.element-charset': defines the charset to be used for encoding HTTP protocol elements. This parameter expects a value of type java.lang.String. If this parameter is not set US-ASCII will be used.
CoreProtocolPNames.HTTP_CONTENT_CHARSET='http.protocol.content-charset': defines the charset to be used per default for content body coding. This parameter expects a value of type java.lang.String. If this parameter is not set ISO-8859-1 will be used.
CoreProtocolPNames.USER_AGENT='http.useragent': defines the content of the User-Agent header. This parameter expects a value of type java.lang.String. If this parameter is not set, HttpClient will automatically generate a value for it.
CoreProtocolPNames.STRICT_TRANSFER_ENCODING='http.protocol.strict-transfer-encoding': defines whether responses with an invalid Transfer-Encoding header should be rejected. This parameter expects a value of type java.lang.Boolean. If this parameter is not set, invalid Transfer-Encoding values will be ignored.
CoreProtocolPNames.USE_EXPECT_CONTINUE='http.protocol.expect-continue': activates the Expect: 100-Continue handshake for the entity enclosing methods. The purpose of the Expect: 100-Continue handshake is to allow the client that is sending a request message with a request body to determine if the origin server is willing to accept the request (based on the request headers) before the client sends the request body. The use of the Expect: 100-continue handshake can result in a noticeable performance improvement for entity enclosing requests (such as POST and PUT) that require the target server's authentication. The Expect: 100-continue handshake should be used with caution, as it may cause problems with HTTP servers and proxies that do not support HTTP/1.1 protocol. This parameter expects a value of type java.lang.Boolean. If this parameter is not set, HttpClient will not attempt to use the handshake.
CoreProtocolPNames.WAIT_FOR_CONTINUE='http.protocol.wait-for-continue': defines the maximum period of time in milliseconds the client should spend waiting for a 100-continue response. This parameter expects a value of type java.lang.Integer. If this parameter is not set HttpClient will wait 3 seconds for a confirmation before resuming the transmission of the request body.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26614996/viewspace-1672958/ ,如需转载,请注明出处,否则将追究法律责任。