HttpClient, an Apache project, is a tool set responsible for creating and maintaining HTTP and related protocols.

The following analysis uses versions: httpClient-4.5.3. jar, httpcore-4.4.6.jar, jdk1.8.0_131 All sample code has been run tested

Send the request

Httpclient’s most important function is to send HTTP requests. Here is how to execute a GET request:

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
try(CloseableHttpResponse response = httpclient.execute(get)) {			
    HttpEntity entity = response.getEntity();
    System.out.println(EntityUtils.toString(entity, "UTF-8"));
} catch (Exception e) {
    e.printStackTrace();
}
Copy the code

Httpclient supports all methods defined in the Http/1.1 specification: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, and the corresponding classes are: HttpGet, HttpHead, HttpPost, HttpPut, HttpDelete, HttpTrace, HttpOptions.

The request URI

A URI (Uniform Resource Identifier) that identifies the resource requested by an application. It usually consists of the protocol version, host name, port (optional), resource path, parameter name (optional), and parameter value (optional). When requested, it can be accessed as a concatenated string:

HttpGet get = new HttpGet("http://www.jianshu.com/p/7021031d6e49?utm_medium=index-banner&utm_source=desktop");
Copy the code

Httpclient also provides the URIBuilder class to simplify the creation and modification of request URIs.

URI uri = new URIBuilder()
		        .setScheme("http")
		        .setHost("www.jianshu.com")
		        .setPath("/p/7021031d6e49")
		        .setParameter("utm_medium"."index-banner")
		        .setParameter("utm_source"."desktop")
		        .build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());
Copy the code

The output

http://www.jianshu.com/p/7021031d6e49?utm_medium=index-banner&utm_source=desktop
Copy the code

An HTTP request is a message sent from a client to a server. The first line of the message contains the request method, URI, and protocol version used.

HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
RequestLine requestLine = get.getRequestLine();
System.out.println(requestLine.getMethod());
System.out.println(requestLine.getUri());
System.out.println(requestLine.getProtocolVersion());
System.out.println(requestLine);
Copy the code

The output

GET http://www.jianshu.com/u/8a3115bb299c HTTP / 1.1 GET http://www.jianshu.com/u/8a3115bb299c HTTP / 1.1Copy the code

Process the response

After receiving and processing the request, the server returns a message to the client. The first line of the message contains the protocol version, status code, and description.

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
try(CloseableHttpResponse response = httpclient.execute(get)) {   
    System.out.println(response.getStatusLine());
    System.out.println(response.getProtocolVersion());
    System.out.println(response.getStatusLine().getStatusCode());
    System.out.println(response.getStatusLine().getReasonPhrase());
    System.out.println(response.getStatusLine().toString());
} catch (Exception e) {
    e.printStackTrace();
}
Copy the code

The output

HTTP/1.1 200 OK
HTTP/1.1
200
OK
HTTP/1.1 200 OK
Copy the code

The response returned by the server is encapsulated in HttpEntity, through which meta information about the request response, such as Content-Type, Content-Length, and Content-Encoding, can be obtained. Meta information must be provided by the server, otherwise it will be null.

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
try(CloseableHttpResponse response = httpclient.execute(get)) {            
    HttpEntity entity = response.getEntity();
    System.out.println(entity.getContentType());
    System.out.println(entity.getContentLength());
    System.out.println(entity.getContentEncoding());
} catch (Exception e) {
    e.printStackTrace();
}
Copy the code

The output

Content-Type: text/html; charset=utf-8
-1
null
Copy the code

HttpEntity provides several methods to read the body. The official documentation recommends using the following methods: httpentity.getContent () and httpentity.writeto (outputStream).

HttpEntity. GetContent () method
CloseableHttpClient httpclient = null;
CloseableHttpResponse response = null;
BufferedReader reader = null;
try {
    httpclient = HttpClients.createDefault();
    HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
    response = httpclient.execute(get);
    HttpEntity entity = response.getEntity();
    reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
    String str = "";
    StringBuilder sb = new StringBuilder();  
    while((str = reader.readLine()) ! = null) { sb.append(str).append("\n");  
    }
    System.out.println(sb);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    CommonUtils.closeReader(reader);
    CommonUtils.closeResponse(response);
    CommonUtils.closeHttpClient(httpclient);
}
Copy the code
CommonUtils
public void closeReader(BufferedReader reader) {
    try {
        if(reader ! = null) { reader.close(); } } catch (Exception e) { e.printStackTrace(); } } public void closeResponse(CloseableHttpResponse response) { try {if(response ! = null) { response.close(); } } catch (Exception e) { e.printStackTrace(); } } public void closeHttpClient(CloseableHttpClient httpclient) { try {if (httpclient != null) {
            httpclient.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Copy the code
HttpEntity writeTo method
CloseableHttpClient httpclient = null;
CloseableHttpResponse response = null;
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
try {
    httpclient = HttpClients.createDefault();
    HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
    response = httpclient.execute(get);
    HttpEntity entity = response.getEntity();
    entity.writeTo(outstream);
    System.out.println(outstream.toString("UTF-8"));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    CommonUtils.closeOutputStream(outstream);
    CommonUtils.closeResponse(response);
    CommonUtils.closeHttpClient(httpclient);
}
Copy the code
CommonUtils
public void closeOutputStream(ByteArrayOutputStream outstream) {
    try {
        if (outstream != null) {
	    outstream.close();
	}
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Copy the code

To ensure the correct release of resources, the flow must be closed when the text is read in the preceding two ways. In addition, HttpClient provides the EntityUtils utility class to facilitate reading of the body, although the official documentation recommends this approach only if the response entity comes from a trusted HTTP server and is known to be of limited length.

EntityUtils. ToString method
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
try(CloseableHttpResponse response = httpclient.execute(get)) {			
    HttpEntity entity = response.getEntity();
    System.out.println(EntityUtils.toString(entity, "UTF-8"));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    CommonUtils.closeHttpClient(httpclient);
}
Copy the code

Entityutils. toString internally closes the input stream in HttpEntity. When the CloseableHttpClient instance is no longer in use, the close method is called to close it.

Response multiple reads via BufferedHttpEntity

For an HttpEntity of a stream type, it cannot be read repeatedly. If you want to read multiple times, you need to cache the HttpEntity somewhere. The simplest way to do this is to use the BufferedHttpEntity class provided by HttpClient.

Httpentity.getcontent ()+BufferedHttpEntity implements multiple reads
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
try(CloseableHttpResponse response = httpclient.execute(get)) {
    HttpEntity entity = response.getEntity();
    BufferedHttpEntity bufferedEntity = new BufferedHttpEntity(entity);
    System.out.println(getEntityContent(bufferedEntity));
    System.out.println(getEntityContent(bufferedEntity));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    CommonUtils.closeHttpClient(httpclient);
}
Copy the code
public String getEntityContent(HttpEntity entity) {
    try(BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"))) {
        String str = "";
        StringBuilder sb = new StringBuilder();  
        while((str = reader.readLine()) ! = null) { sb.append(str).append("\n");  
        }
        return sb.toString();
    } catch (Exception e) {
        e.printStackTrace();
        return ""; }}Copy the code
HttpEntity. WriteTo +BufferedHttpEntity implements multiple reads
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
try(CloseableHttpResponse response = httpclient.execute(get)) {
    HttpEntity entity = response.getEntity();
    BufferedHttpEntity bufferedEntity = new BufferedHttpEntity(entity);
    System.out.println(getContentByWriteTo(bufferedEntity));
    System.out.println(getContentByWriteTo(bufferedEntity));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    CommonUtils.closeHttpClient(httpclient);
}
Copy the code
public String getContentByWriteTo(HttpEntity entity) {
    try(ByteArrayOutputStream outstream = new ByteArrayOutputStream()) {
        entity.writeTo(outstream);
        return outstream.toString("UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
        return ""; }}Copy the code
Entityutils. toString+BufferedHttpEntity implements multiple reads
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.jianshu.com/u/8a3115bb299c");
try(CloseableHttpResponse response = httpclient.execute(get)) {            
    HttpEntity entity = response.getEntity();
    BufferedHttpEntity bufferedEntity = new BufferedHttpEntity(entity);
    System.out.println(EntityUtils.toString(bufferedEntity, "UTF-8"));
    System.out.println(EntityUtils.toString(bufferedEntity, "UTF-8"));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    CommonUtils.closeHttpClient(httpclient);
}
Copy the code

At this point, through HttpClient, the simple implementation of HTTP GET request sending and response processing.