HttpClient Tutorial: HttpClient Http execution method.

1.1. Execution request

HttpClient most basic function is to perform Http method. Http performing a method of interaction involves one or more Http request / response Http, typically this process is automatically processed HttpClient, transparent to the user. Http request user only needs to provide an object, HttpClient will send an http request to the target server, and receives a response from the server, http request if unsuccessful implementation, HttpClient throws strange.

Here is a very simple example http request execution:

CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://www.yeetrack.com/"); CloseableHttpResponse response = httpclient.execute(httpget); try { <...> } finally { response.close(); }

1.1.1. Http request

All Http request has a request column (request line), including the method name, URI, and the version number Http request.

HttpClient supports HTTP / 1.1 This version of the definition of all Http methods: GET, HEAD, POST, PUT, DELETE, 'TRACE and OPTIONS. For each http method, HttpClient defines a corresponding class: HttpGet, HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace and HttpOpquertions`.

Request-URI or Uniform Resource Locator, Http request to indicate resources. Http request URIS include a protocol name, host name, host port (optional), resource path, Query (optional) and clip information (optional).

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

HttpClient provides URIBuilder tools to simplify the creation and modification of URIs.

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());

The code will be output in the console:

http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=

1.1.2. HTTP response

Http server receives the client's request, it will be resolved, then the response to the client, the response is HTTP response.HTTP response is the first line of the HTTP version number, then the response status code and response content.

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); System.out.println(response.getProtocolVersion()); System.out.println(response.getStatusLine().getStatusCode()); System.out.println(response.getStatusLine().getReasonPhrase()); System.out.println(response.getStatusLine().toString());

The code will be output in the console:

HTTP/1.1 200 OK HTTP/1.1 200 OK

1.1.3. Header

Http message may contain a series of message header, used to describe an http message, such as message length, message type and the like. HttpClient provides an API to get, add, modify, traverse the message header.

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.addHeader("Set-Cookie", "c1=a; path=/; domain=yeetrack.com"); response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; domain=\"yeetrack.com\""); 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);

The code will be output in the console:

Set-Cookie: c1=a; path=/; domain=yeetrack.com Set-Cookie: c2=b; path="/", c3=c; domain="yeetrack.com" 2

The most effective access to the specified type of message header or a method using HeaderIterator interface.

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.addHeader("Set-Cookie", "c1=a; path=/; domain=yeetrack.com"); response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; domain=\"yeetrack.com\""); HeaderIterator it = response.headerIterator("Set-Cookie"); while (it.hasNext()) { System.out.println(it.next()); }

The code will be output in the console:

Set-Cookie: c1=a; path=/; domain=yeetrack.com Set-Cookie: c2=b; path="/", c3=c; domain="yeetrack.com"

HeaderIterator also provides a convenient way, the message parsing into individual Http header message element.

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK"); response.addHeader("Set-Cookie", "c1=a; path=/; domain=yeetrack.com"); response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; domain=\"yeetrack.com\""); 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]); } }

The code will be output in the console:

c1 = a path=/ domain=yeetrack.com c2 = b path=/ c3 = c domain=yeetrack.com

1.1.4. Http entity

Http http message may carry an entity, the entity can be either http http request, or may be a http response. Http entity can be found at http request or response in some, but not necessarily. Http specification defines two requests comprising: POST and PUT. HTTP response typically comprises a content entity. Of course, this rule there are exceptions, such as response Head method, no content 204, 304 or 205 does not modify the contents of resource resetting.

HttpClient according to different sources, divided in three different entities Http content.

streamed: Http by streaming content is to accept or generated on the fly. In particular, streamed this category includes entities acquired content from http response. Generally, streamed entity is not repeatable.

self-contained: The content is in memory or obtained by means that are independent from a connection or other entity. type of self-contained entity content is usually reproducible. This type of entity is typically used to close the http request.

wrapping: This type of content is obtained from http another entity.

When reading from the Http response, to distinguish between three upper connection manager is very important. Request class entity typically created by an application, by the HttpClient sent to the server, the request in the entity class, the difference between streamed and self-contained two types is not important. In this case, generally considered to be non-repeatable streamed entity type, when an entity repeatable self-contained.

1.1.4.1. Repeatable entity

Entity is a reproducible, which means that it contains the content may be read many times. Only this once, read many self contained (self-contained) entities can do (such as ByteArrayEntity or StringEntity).

1.1.4.2. Use Http entity

Due to a Http entity can represent both binary content, but also represents the textual content, so Http entity to support the character encoding (in order to support the latter, that is, text content).

When you need to perform a full content or Http request Http request has been successful, the server to send a response to the client, Http entity will be created.

If you want to read the contents Http entity, we can use the method getContent HttpEntity class to obtain the input stream entity (a java.io.InputStream), or with writeTo (OutputStream) Method HttpEntity class to obtain an output stream, this method All writes to the content of a given stream.

When the entity class has been accepted, we can use getContentType HttpEntity class () and getContentLength () method reads the Content-Type and Content-Length two header message (if any). Since Content-Type mime-types comprising a character code, such as text / plain or text / html, HttpEntity class getContentEncoding () method is to read the code. If the header information does not exist, getContentLength () returns -1, getContentType () returns NULL. If the Content-Type information exists, it will return a Header class.

When creating Http entity to send a message, you need to additional meta information.

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);

The code will be output in the console:

Content-Type: text/plain; charset=utf-8 17 important message 17

1.1.5. Ensure that the underlying connection is released resources

To ensure that system resources are properly released, we either manage content flow Http entity, either close Http response.

CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://www.yeetrack.com/"); CloseableHttpResponse response = httpclient.execute(httpget); try { HttpEntity entity = response.getEntity(); if (entity != null) { InputStream ×××tream = entity.getContent(); try { // do something useful } finally { ×××tream.close(); } } } finally { response.close(); }

Close Close Http Http solid content stream and in response to the difference that the former is related to maintaining consumed via http Http substantial contents, which then closes immediately discarded http connection.

Please note HttpEntity of writeTo (OutputStream) method, when Http entity is written to the OutputStream, but also to ensure free system resources. If you call the HttpEntity of getContent () method in this way, then it will have an instance java.io.InpputStream, we need to close the stream finally in.

But this is the case, we only need to obtain a fraction Http response content, and acquires entire contents, connected achieve repeatability too costly, then we can be closed off in response to the content inputted by the way, the output stream .

CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://www.yeetrack.com/"); CloseableHttpResponse response = httpclient.execute(httpget); try { HttpEntity entity = response.getEntity(); if (entity != null) { InputStream ×××tream = entity.getContent(); int byteOne = ×××tream.read(); int byteTwo = ×××tream.read(); // Do not need the rest } } finally { response.close(); }

After performing the above code, the connection becomes unavailable, all resources are released.

1.1.6. Http entity consume content

HttpClient recommended HttpEntity of getConent () method or HttpEntity of writeTo (OutputStream) way to consume content Http entity. HttpClient also provides EntityUtils this class, this class provides static methods can be more easily read the content and information Http entities. And compared to the content in the stream reads java.io.InputStream, the method provided may be read EntityUtils Http entity in the form of a string or byte array. However, it is strongly not recommended EntityUtils this class, unless the response issued by the target server is trusted, and http response length entity does not become too large.

CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://www.yeetrack.com/"); 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(); }

In some cases, we hope to repeat Http read the contents of the entity. This requires the entity Http content caching in memory or disk. The easiest way is to be converted into the Entity Http BufferedHttpEntity, so that the original content Http entity put into the buffer memory. Later we will content BufferedHttpEntity can be read repeatedly.

CloseableHttpResponse response = <...> HttpEntity entity = response.getEntity(); if (entity != null) { entity = new BufferedHttpEntity(entity); }

1.1.7. Http entity created content

Providing a HttpClient classes substantial contents can be output efficiently Http connection via http. (The original is HttpClient provides several classes that can be used to efficiently stream out content though HTTP connections. Feeling thought should be throught) these classes common data types covered by HttpClient offered, such as String, byte array input stream, and file type: StringEntity, ByteArrayEntity, InputStreamEntity, FileEntity.

File file = new File("somefile.txt"); FileEntity entity = new FileEntity(file, ContentType.create("text/plain", "UTF-8")); HttpPost httppost = new HttpPost("http://www.yeetrack.com/action.do"); httppost.setEntity(entity);

Note that since InputStreamEntity read only once the data stream from the lower layer, so it is not repeated. Recommended by this class inherits HttpEntity self-contained customize HttpEntity class, rather than directly using InputStreamEntity this class. FileEntity is a good starting point (FileEntity is inherited HttpEntity).

1.7.1.1. HTML form

Many applications need to simulate the process of submitting Html form, for example, a landing site or the content of the input submitted to the server. HttpClient provides UrlEncodedFormEntity this class to help achieve this process.

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://www.yeetrack.com/handler.do"); httppost.setEntity(entity);

UrlEncodedFormEntity example uses the so-called Url coded way we encode parameters, the result is as follows:

param1=value1&param2=value2

1.1.7.2. Content block

In general, it is recommended to make their own HttpClient to select the most appropriate transfer encoding characteristics according Http messaging. Of course, if you have to manual control it is also possible, by setting the HttpEntity setChunked () is true. Please note: HttpClient this parameter will only be seen as a suggestion. If Http versions (such as http 1.0) does not support the content block, then this parameter is ignored.

StringEntity entity = new StringEntity("important message", ContentType.create("plain/text", Consts.UTF_8)); entity.setChunked(true); HttpPost httppost = new HttpPost("http://www.yeetrack.com/acrtion.do"); httppost.setEntity(entity);

1.1.8. Response handlers

The easiest and most convenient way to process http response is to use ResponseHandler interface that has handleResponse (HttpResponse response) method. Using this method, users need not be concerned about http connection manager. When ResponseHandler, HttpClient will automatically Http Http connection release to the manager, even if http request fails or throws an exception.

return gson.fromJson (reader, MyJsonObject.class);}}; // set ResponseHandler, http method when executed, returns MyJsonObject object. MyJsonObject myjson = client.execute (httpget, rh);

1.2. HttpClient Interface

For Http request execution process is, HttpClient interface has an essential role. HttpClient interface does not make a request of the process Http particularly limited and detailed regulations, connection management, state management, licensing information, and these redirection processing functions are implemented separately. So users can more easily extend the functionality of the interface (such as caching response content).

In general, HttpClient is actually a series of special handler or implement policy interface, these handler (Test Interface) is responsible for a particular aspect of the process Http protocol, such as redirection, an authentication process for connection persistence and keep alive decision time duration. This allows a user-defined parameters instead of the default configuration, personalized functions.

ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy () {@Override public long getKeepAliveDuration (HttpResponse response, HttpContext context) {long keepAlive = super.getKeepAliveDuration (response, context); if (keepAlive == -1) {// If the server is not set keep- this parameter is alive, we put it provided five seconds keepAlive = 5000;} return keepAlive;}}; // our own custom httpclient CloseableHttpClient httpclient = HttpClients.custom () .setKeepAliveStrategy (keepAliveStrat) .build ();

1.2.1.HttpClient thread safety

HttpClient has achieved a thread-safe. So when users want to instantiate HttpClient, but also supports the use of multiple requests.

1.2.2.HttpClient memory allocation

When a CloseableHttpClient instance is no longer used, and its scope is about to fail, and its associated connection must be closed off method can be called close CloseableHttpClient () method.

CloseableHttpClient httpclient = HttpClients.createDefault(); try { <...> } finally { //关闭连接 httpclient.close(); }

1.3.Http execution context

Initially, the Http is designed as a stateless request for - response protocol. However, in actual use, we hope to some logically related request - in response, the holding state information. To make the application may maintain a persistent state Http, HttpClient allows http Http connection in a particular execution context. If the same context ongoing http request, then the request can be assigned to a logical session. And HTTP context is a java.util.Map <String, Object> functionally similar. It is actually a collection of arbitrary named value. An application can request value before the filling in the context Http, a request may be checked after the implementation of the context.

HttpContext can contain any type of object, so if shared in a multithreaded context unsafe. Each thread is recommended only contains its own http context.

Http request during execution, HttpClient will automatically add the following property to the context Http:

HttpConnection example, showing the connection between the client and the server

Examples HttpHost, expressed wooden package server you want to connect

Examples HttpRoute, showing all of the connection route

Examples of HttpRequest indicates Http request. In the context of the implementation of the final status HttpRequest object on behalf of http messages. Http / 1.0 and Http / 1.1 by default use relative uri. But if you use a non-tunnel mode proxy server, you will use the uri absolute path.

Examples HttpResponse, expressed Http response

java.lang.Boolean object representing whether the transmission was successful request to the target server

RequestConfig object that represents the configuration information http request

java.util.List <Uri> objects, indicating that all addresses Http redirect response

HttpClientContext we can use this adapter to simplify the process of interaction and context.

HttpContext context = <...> HttpClientContext clientContext = HttpClientContext.adapt(context); HttpHost target = clientContext.getTargetHost(); HttpRequest request = clientContext.getRequest(); HttpResponse response = clientContext.getResponse(); RequestConfig config = clientContext.getRequestConfig();

A plurality of logical Http request the same session, the same Http context should be executed, so that you can automatically transfer session context and state information in the http request.

In the following example, we begin with the parameter settings will be saved in this context, and will be applied to subsequent http requests (source English spelling error).

CloseableHttpClient httpclient = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(1000) .setConnectTimeout(1000) .build(); HttpGet httpget1 = new HttpGet("http://www.yeetrack.com/1"); httpget1.setConfig(requestConfig); CloseableHttpResponse response1 = httpclient.execute(httpget1, context); try { HttpEntity entity1 = response1.getEntity(); } finally { response1.close(); } //httpget2被执行时,也会使用httpget1的上下文 HttpGet httpget2 = new HttpGet("http://www.yeetrack.com/2"); CloseableHttpResponse response2 = httpclient.execute(httpget2, context); try { HttpEntity entity2 = response2.getEntity(); } finally { response2.close(); }

1.4 Exception Handling

HttpClient are two types of thrown exceptions, one is java.io.IOException, when faced with I / O exception is thrown (socket timeout is reset or socket); HttpException The other is, indicates failure Http such as Http protocol used incorrectly. It is generally believed that when the fatal I / O error, repairable, and Http protocol error is fatal, the error is not automatically repaired.

1.4.1.HTTP transport security

Http protocol can not meet all types of application scenarios, we need to know that. Http protocol request is a simple protocol for / response, it was originally designed to support static or dynamically generated content retrieval, and before no one ever let it support transactional operations. For example, successful reception Http server, after processing the request, generates a response message, and sends a status code to the client, this process is guaranteed to be Http protocol. However, if the client due to the read timeout, cancel the request or the system crashes resulting in failure to receive a response, the server will not roll back the transaction. If the client to resend the request, the server will repeat the resolution, the implementation of this transaction. In some cases, this can result in data corruption and inconsistent application state of the application.

Http even if the original design does not support transactional operations, but it can still serve some of the key programs as the transport protocol. To ensure the security Http transporting layer system must ensure idempotent http method at the application layer (To ensure HTTP transport layer safety the system must ensure the idempotency of HTTP methods on the application layer).

1.4.2 Method of idempotent

HTTP / 1.1 specification is defined idempotent methods, 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 needs to deal with the same method correctly performed multiple times the impact. Add a uniqueness id be able to avoid having repeat the same logical request, the problem is solved.

Please know that this problem is not just HttpClient will have, will encounter Http method is not idempotent problem-based application browser.

The default method for non-solid HttpClient get, head seen idempotent method method, the physical method post, put the method seen as non-idempotent method.

1.4.3. Abnormal auto repair

By default, HttpClient tries to automatically fix I / O exception. This automatic repair is limited to repair a few exceptions generally recognized as safe.

HttpClient will not try to repair any logical or http protocol error (ie derived from HttpException abnormal).

HttpClient will automatically send power again like method (if the first fails.

HttpClient will automatically send again encounter abnormal transport methods, provided that the Http request still maintained a connection (for example, http request does not have to send all the target server, HttpClient will try to send again).

1.4.4. Retry request handler

If you want to customize exception handling mechanism, we need to implement HttpRequestRetryHandler interface.

HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler () {public boolean retryRequest (IOException exception, int executionCount, HttpContext context) {if (executionCount> = 5) {// If the retry has five times, to give return false;} if (exception × ×× tanceof InterruptedIOException) {// timeout return false;} if (exception ××× tanceof UnknownHostException) {// the target server is unreachable return false;} if (exception ××× tanceof ConnectTimeoutException) {// return false connection refused ;} if (exception ××× tanceof SSLException) {// ssl handshake abnormal return false;} HttpClientContext clientContext = HttpClientContext.adapt (context); HttpRequest request = clientContext.getRequest ();! boolean idempotent = (request ××× tanceof HttpEntityEnclosingRequest); if (idempotent) {// if the request is idempotent, try again return true;} return false;}}; CloseableHttpClient httpclient = HttpClients.custom ().setRetryHandler(myRetryHandler) .build();

1.5. Termination request

Sometimes because the target server load is too high or there are too many clients request backlog, http request can not be finished within the specified time. This time the request is terminated, the release of blocking I / O process, it is very necessary. Http request by HttpClient performed in any state can be stopped by calling abort HttpUriRequest () method. This method is thread-safe, and can be called at any thread. When Http request is terminated, this thread (even now blocking I / O) also by throwing a InterruptedIOException an exception to free up resources.

1.6. Http protocol interceptors

HTTP protocol interceptor is an implementation of the HTTP protocol to a particular aspect of the program code. Typically, the protocol interceptor will be added to one or more headers message sent or received message. Protocol interceptor may operate content entity message - the message content compression / decompression is a good example. Typically, this is done by using the "decoration" development model, a wrapper entity class used to decorate the original entity to achieve. An interceptor can be combined to form a logical unit.

Protocol interceptors can collaborate by sharing information - such as the processing status - execution context via HTTP. Http protocol interceptor can use one or more processing context storage state continuation requests.

Typically, as long as the interceptor does not depend on a particular state http context, the order of execution does not matter intercept. If the protocol interceptors have interdependencies, must be performed in a particular order, they should be added to the protocol processor in a particular order.

Protocol processor must be thread safe. Similar to servlets, protocol interceptors should not use variable entity, unless access these variables are (thread-safe) synchronized.

Here is an example, how to handle in a continuous state of the recording request and describe the local context:

CloseableHttpClient httpclient = HttpClients.custom() .addInterceptorLast(new HttpRequestInterceptor() { public void process( final HttpRequest request, final HttpContext context) throws HttpException, IOException { //AtomicInteger是个线程安全的整型类 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://www.yeetrack.com/"); for (int i = 0; i < 10; i++) { CloseableHttpResponse response = httpclient.execute(httpget, localContext); try { HttpEntity entity = response.getEntity(); } finally { response.close(); } }

The above codes when sending http request, will automatically add the Count this header, you can use wireshark capture view.

1.7.1. Redirect process

HttpClient will automatically handle all types of redirection, Http specification except those expressly prohibited redirection. See Other (status code 303) redirects on POST and PUT requests are converted to GET requests as required by the HTTP specification. We can use custom redirection policy to relax norms for Post Http redirection method restrictions.

// LaxRedirectStrategy can automatically redirect all HEAD, GET, POST request to lift restrictions on post redirected request http specification. LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy (); CloseableHttpClient httpclient = HttpClients.custom () .setRedirectStrategy (redirectStrategy) .build ();

HttpClient during execution request message is often necessary to rewrite request. HTTP / 1.0 and HTTP / 1.1 uses the default path opposite uri. Similarly, the original request may be one or more times redirection. Most end of the path may be used to explain the initial request and context. Method URIUtils class can resolve the absolute path to intercept requests to a final construct. This method includes the final identifier or a fragment of the original request.

CloseableHttpClient httpclient = HttpClients.createDefault(); HttpClientContext context = HttpClientContext.create(); HttpGet httpget = new HttpGet("http://www.yeetrack.com: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()); // 一般会取得一个绝对路径的uri } finally { response.close(); }

Product is slightly Library http://www.pinlue.com/

Guess you like

Origin blog.51cto.com/14325182/2409620