1, the introduction of

HttpClient is a subproject of Apache Jakarta Common that provides an efficient, up-to-date, feature-rich client programming toolkit that supports the latest versions and recommendations of the HTTP protocol. HttpClient has been used in many projects, such as Cactus and HTMLUnit, two other well-known open source projects on Apache Jakarta that use HttpClient.

HttpClient compared to the traditional JDK URLConnection, increase the ease of use and flexibility, it is not only the client to send HTTP requests become easy, but also convenient for developers to test the interface (based on HTTP protocol), that is, improve the efficiency of development. It is also convenient to improve code robustness. Therefore, it is very important to master HttpClient. After mastering HttpClient, I believe that the understanding of HTTP protocol will be more in-depth.

2. Introduce dependencies

HttpClient is a tripartite tool that first needs to introduce dependencies. As follows:

<! -- The 5.x version is used here, you can import the version according to your own situation -->
<dependency>
     <groupId>org.apache.httpcomponents.client5</groupId>
     <artifactId>httpclient5</artifactId>
     <version>5.1.1</version>
</dependency>
Copy the code

3. Obtain the client

To use the HttpClient, you need to obtain the HttpClient object in the following ways

  1. Default creation mode

    // Get the default HttpClient configuration
    CloseableHttpClient httpClient = HttpClients.createDefault();
    Copy the code
  2. Created based on the system configuration

    // This is done by creating an HttpClient based on the system configuration
    CloseableHttpClient httpClient = HttpClients.createSystem();
    Copy the code

    The following JVM startup parameters can be set at project startup time:

    • HTTP. UserAgent agent configuration
    • Http. keepAlive Configures keepAlive data
  3. Custom creation

    // This way you can set some default values at creation time
    CloseableHttpClient  httpClient = HttpClients.custom()
                         .setDefaultHeaders(Collections.emptyList())   // Set the default request header
                         .setDefaultRequestConfig(RequestConfig.DEFAULT)  // Set the default configuration
                         .build();
    Copy the code

4. Set parameters

HttpClient can do this by setting the global configuration when the HttpClient object is created, or by setting the request configuration for a single request.

  1. Creating a Configuration Object

      // Create the request configuration information
    RequestConfig  requestConfig = RequestConfig.custom()
         // Set connection timeout
        .setConnectTimeout(Timeout.of(3000, TimeUnit.MILLISECONDS))
        // Set the response timeout
        .setResponseTimeout(3000, TimeUnit.MILLISECONDS) 
        // Set the timeout for getting links from the connection pool
        .setConnectionRequestTimeout(3000, TimeUnit.MILLISECONDS)
        .build();
    
    
    Copy the code
  2. Setting global Configuration

    // This way you can set some default values at creation time
    CloseableHttpClient  httpClient = HttpClients.custom()
                         .setDefaultHeaders(Collections.emptyList())   // Set the default request header
                         .setDefaultRequestConfig(requestConfig)  // Set the default configuration
                         .build();
    Copy the code
  3. Single request Settings configuration

    // Create a GET request object
    HttpGet httpGet = new HttpGet(uri);
    
    // Set the request parameters
    httpGet.setConfig(requestConfig);
    Copy the code

5. Set the request header

Setting a custom request header or changing the value of conent-type can be done in either of the following ways:

  1. Set the common request header

    List<Header> headers = new ArrayList<>();
    headers.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON));
    headers.add(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, x-gzip, deflate"));
    headers.add(new BasicHeader(HttpHeaders.CONNECTION, "keep-alive"));
    
    // Create a default httpClient
    CloseableHttpClient  httpClient = HttpClients.custom()
        .setDefaultHeaders(headers)   // Set the default request header
        .build()
    Copy the code
  2. Single request sets the request header

    // Create a POST request
    HttpPost httpPost = new HttpPost(uri);
    // Add the content-type request header
    httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED);
    // Add the accept header
    httpPost.addHeader(new BasicHeader(HttpHeaders.ACCEPT, "* / *"));
    Copy the code

6. Send the request

A GET request

All parameters of a GET request are concatenated directly after the URL. There are two ways to do this in HttpClient, as follows:

  1. Request parameters are concatenated directly after the request path

    String name = URLEncoder.encode("Zhang"."utf-8");
    // Request path and parameters
    String url = "http://localhost:10010/user/params? age=20&name=" + name;
    
    // Create a GET request object
    HttpGet httpGet = new HttpGet(url);
    // Call the HttpClient's execute method to execute the request
    CloseableHttpResponse response = httpClient.execute(httpGet);
    // Get the request status
    int code = response.getCode();
    // If the request succeeds
    if(code == HttpStatus.SC_OK){
        LOGGER.info("Response result: {}", EntityUtils.toString(response.getEntity()));
    }
    Copy the code
  2. Build the request path with URIBuilder

    
    // Build the request path and parameters
    URL url = new URL("http://localhost:10010/user/params");
    URI uri = new URIBuilder()
        .setScheme(url.getProtocol())
        .setHost(url.getHost())
        .setPort(url.getPort())
        .setPath(url.getPath())
        // Build parameters
        .setParameters(
            new BasicNameValuePair("name"."Zhang"),
            new BasicNameValuePair("age"."20")
         ).build();
    
    // Create a GET request object
    HttpGet httpGet = new HttpGet(uri);
    // Call the HttpClient's execute method to execute the request
    CloseableHttpResponse response = httpClient.execute(httpGet);
    // Get the request status
    int code = response.getCode();
    // If the request succeeds
    if(code == HttpStatus.SC_OK){
        LOGGER.info("Response result: {}", EntityUtils.toString(response.getEntity()));
    }
    Copy the code

A POST request

As we all know, the data in an HTTP POST request is contained in the request body. POST requests send data in The HttpClient by calling the setEntity(HttpEntity Entity) method of the HttpPost class to set the content of the message.

  1. Sending JSON Data

    Sending JSON data in HttpClient can be implemented using the StringHttpEntity class, as shown below:

    // Request parameters
    String url = "http://localhost:10010/user/body";
    // Create a GET request object
    HttpPost httpPost = new HttpPost(url);
    // Build the object
    User user = new User();
    user.setName("Zhang")
        .setAge(20)
        .setAddress(new Address()
                    .setCounty("China")
                    .setCity("Beijing"))
        .setAihao(Arrays.asList("Running"."Climb"."Reading"));
    
    // Create a string entity object
    HttpEntity httpEntity = new StringEntity(JSON.toJSONString(user));
    httpPost.setEntity(httpEntity);
    
    // Send a POST request
    httpClient.execute(httpPost);
    Copy the code
  2. Simulate form data

    In actual use, there can be a need to simulate the form form request data, HttpClent can also be very convenient to implement form submission function. The operation steps are as follows:

    • Modify the contentType

      // Create a ContentType object for the form mode
      ContentType contentType = ContentType.create("application/x-www-form-urlencoded", StandardCharsets.UTF_8);
      // Add to the HttpPost header
      httpPost.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
      Copy the code
    • Create request data HttpEntity

      Method 1: Concatenate the request data yourself and create a StringEntity object
      String query = "name="+ URLEncoder.encode("Zhang"."utf-8") +"&age=20";
      HttpEntity httpEntity = new StringEntity(query);
      
      // Create an HttpEntity using UrlEncodedFormEntity
      HttpEntity httpEntity = new UrlEncodedFormEntity(
          Arrays.asList(new BasicNameValuePair("name"."Zhang"),
                        new BasicNameValuePair("age"."20")),
          StandardCharsets.UTF_8
      );
      
      // Set the HttpEntity to the HttpPost
      httpPost.setEntity(httpEntity);
      Copy the code

    The complete code is shown below:

    
    // Create a POST request object
    HttpPost httpPost = new HttpPost("http://localhost:10010/user/map");
    / * String query = "name =" + URLEncoder. Encode (" zhang ", "utf-8") + "& age = 20"; HttpEntity httpEntity = new StringEntity(query); * /
    
    HttpEntity httpEntity = new UrlEncodedFormEntity(
        Arrays.asList(new BasicNameValuePair("name"."Zhang"),
                      new BasicNameValuePair("age"."20")),
        StandardCharsets.UTF_8
    );
    
    // Set the request data
    httpPost.setEntity(httpEntity);
    // Set the request header
    ContentType contentType = ContentType.APPLICATION_FORM_URLENCODED.withCharset(StandardCharsets.UTF_8);
    httpPost.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
    // Call the HttpClient's execute method to execute the request
    CloseableHttpResponse response = httpClient.execute(httpPost);
    // Get the request status
    int code = response.getCode();
    // If the request succeeds
    if(code == HttpStatus.SC_OK){
        LOGGER.info("Response result: {}", EntityUtils.toString(response.getEntity()));
    }
    Copy the code

7. Upload and download

upload

HttpClient upload function is very convenient, you can use the MultipartEntityBuilder directly to build HttpEntity.

// The file to upload
File file = new File("F:/20150703212056_Yxi4L.jpeg");

// Create an object
MultipartEntityBuilder builder = MultipartEntityBuilder.create();

// Add the binary message body
builder.addBinaryBody("file", file);

// Text messages can also be added
ContentType contentType = ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8);
builder.addTextBody("name"."Zhang", contentType);

// Build the body of the message with MultipartEntityBuilder
HttpEntity httpEntity = builder.build();
HttpPost httpPost = new HttpPost("http://localhost:10010/user/upload");
httpPost.setEntity(httpEntity);
CloseableHttpResponse response = httpClient.execute(httpPost);
// Get the request status
int code = response.getCode();
// If the request succeeds
if(code == HttpStatus.SC_OK){
    LOGGER.info("Response result: {}", EntityUtils.toString(response.getEntity()));
}

Copy the code

download

The HttpClient download is also quite simple, just send the request, determine the success of the request, read the input stream, and save to the response path, as follows:

// Request the download path
HttpGet httpGet = new HttpGet("http://localhost:10010/user/downLoad");
CloseableHttpResponse response = httpClient.execute(httpGet);

// If the request succeeds
if (response.getCode() == HttpStatus.SC_OK){

    // Obtain the File Name of the downloaded File. The file-name header needs to be customized on the server
    Header header = response.getFirstHeader("File-Name");
    String value = header.getValue();

    // Read data
    byte[] bytes = EntityUtils.toByteArray(response.getEntity());
    try (OutputStream outputStream = new FileOutputStream("F:/" + value);){
        outputStream.write(bytes);
        outputStream.flush();
    }
}
Copy the code

8. Response processing

The response is encapsulated as a CloseableHttpResponse object in the HttpClient, where the following data can be obtained:

  1. GetCode () gets the response status
  2. GetEntity () gets the response data
 // If the request succeeds
if(code == HttpStatus.SC_OK){
    LOGGER.info("Response result: {}", EntityUtils.toString(response.getEntity()));
}
Copy the code

HttpClient provides an EntityUtils utility class that converts a response HttpEntity into a byte array or string

// Convert to a string
EntityUtils.toString(response.getEntity());

// Convert to a byte array
EntityUtils.toByteArray(response.getEntity());
Copy the code

In addition to the above, custom data types can be passed in response to the handler when the execute() method of HttpClient is called. Returns a custom Response object, as shown below

// Customize the response object
@Data
@Accessors(chain = true)
class  Response {
    // Response status
    private int code;
    // Response description
    private String msg;
    / / response body
    private String body;
}

// Customize the response handling class when invoking execute
 Response execute = httpClient.execute(httpGet, response -> {
            return new Response().setCode(response.getCode())
                .setMsg(response.getReasonPhrase())
                .setBody(EntityUtils.toString(response.getEntity(),                 
                                              StandardCharsets.UTF_8));
        });

Copy the code

9. Conversation retention

In actual projects, it is often encountered that you need to log in before accessing other interfaces. Therefore, the HttpClient provides the HttpClientContext class, which can be very good implementation of the session persistence function.

  • createHttpClientContext
  • The object created in the first step is passed in the execute() method

As follows:

// Create an HttpClientContext object
HttpContext httpContext = new BasicHttpContext();
httpContext.setAttribute("name"."zhangsan");
HttpClientContext httpClientContext = HttpClientContext.adapt(httpContext);

/ / login
httpClient.execute(new HttpPost(""), httpClientContext);

// Get data
httpClient.execute(new HttpGet(""), httpClientContext);
Copy the code

10 and summarize

Here is just the use of HttpClient to do a simple introduction, play a role, in fact, HttpClient provides a very powerful function, in the next layer of HttpClient analysis, slowly uncover its mystery.