Posting with Apache HttpClient – 用Apache HttpClient发帖

最后修改: 2014年 12月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll POST with the HttpClient 4, first using authorization, then the fluent HttpClient API.

在本教程中,我们将用HttpClient 4进行POST,首先使用授权,然后使用流畅的HttpClient API。

Finally, we’ll discuss how to upload a file using HttpClient.

最后,我们将讨论如何使用HttpClient上传一个文件。

2. Basic POST

2.基本的POST

First, let’s go over a simple example and send a POST request using HttpClient.

首先,让我们看一个简单的例子,使用HttpClient发送一个POST请求。

We’ll do a POST with two parameters, “username” and “password“:

我们将做一个带有两个参数的POST,”用户名“和”密码“。

@Test
public void whenSendPostRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("username", "John"));
    params.add(new BasicNameValuePair("password", "pass"));
    httpPost.setEntity(new UrlEncodedFormEntity(params));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we used a List of NameValuePair to include parameters in the POST request.

注意我们如何使用List of NameValuePair在POST请求中包含参数。

3. POST With Authorization

3.带有授权的POST

Next, let’s see how to do a POST with Authentication credentials using the HttpClient.

接下来,让我们看看如何使用HttpClient做一个带有认证凭证的POST。

In the following example, we’ll send a POST request to a URL secured with Basic Authentication by adding an Authorization header:

在下面的例子中,我们将通过添加授权头向一个有基本认证的URL发送一个POST请求。

@Test
public void whenSendPostRequestWithAuthorizationUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException, AuthenticationException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    httpPost.setEntity(new StringEntity("test post"));
    UsernamePasswordCredentials creds
      = new UsernamePasswordCredentials("John", "pass");
    httpPost.addHeader(new BasicScheme().authenticate(creds, httpPost, null));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

4. POST With JSON

4.使用JSON的POST

Now let’s see how to send a POST request with a JSON body using the HttpClient.

现在让我们看看如何使用HttpClient发送一个带有JSON主体的POST请求。

In the following example, we’ll send some person information (id, name) as JSON:

在下面的例子中,我们将发送一些信息(id, name)作为JSON。

@Test
public void whenPostJsonUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    String json = "{"id":1,"name":"John"}";
    StringEntity entity = new StringEntity(json);
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

Note how we’re using the StringEntity to set the body of the request.

注意我们如何使用StringEntity来设置请求的主体。

We’re also setting the ContentType header to application/json to give the server the necessary information about the representation of the content we’re sending.

我们还将ContentType头设置为application/json,以便向服务器提供关于我们所发送内容的代表的必要信息。

5. POST With the HttpClient Fluent API

5.使用HttpClient Fluent API的POST

Next, let’s POST with the HttpClient Fluent API.

接下来,让我们用HttpClient Fluent API进行POST。

We’ll send a request with two parameters, “username” and “password“:

我们将发送一个带有两个参数的请求,”用户名“和”密码“。

@Test
public void whenPostFormUsingHttpClientFluentAPI_thenCorrect() 
  throws ClientProtocolException, IOException {
    HttpResponse response = Request.Post("http://www.example.com").bodyForm(
      Form.form().add("username", "John").add("password", "pass").build())
      .execute().returnResponse();

    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

6. POST Multipart Request

<6.POST多部分请求

Now let’s POST a Multipart Request.

现在让我们发送一个多部分请求。

We’ll post a File, username, and password using MultipartEntityBuilder:

我们将使用MultipartEntityBuilder发布一个文件、用户名和密码:

@Test
public void whenSendMultipartRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("username", "John");
    builder.addTextBody("password", "pass");
    builder.addBinaryBody(
      "file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");

    HttpEntity multipart = builder.build();
    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

7. Upload a File Using HttpClient

7.使用HttpClient上传一个文件

Next, let’s see how to upload a File using the HttpClient.

接下来,让我们看看如何使用HttpClient上传文件

We’ll upload the “test.txt” file using MultipartEntityBuilder:

我们将使用MultipartEntityBuilder上传”test.txt“文件:

@Test
public void whenUploadFileUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody(
      "file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    HttpEntity multipart = builder.build();
    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

8. Get File Upload Progress

8.获取文件上传进度

Finally, let’s see how to get the progress of File upload using HttpClient.

最后,让我们看看如何使用HttpClient获得File的上传进度。

In the following example, we’ll extend the HttpEntityWrapper to gain visibility into the upload process.

在下面的例子中,我们将扩展HttpEntityWrapper以获得对上传过程的可见性。

First, here’s the upload method:

首先,这里是上传方法。

@Test
public void whenGetUploadFileProgressUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody(
      "file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    HttpEntity multipart = builder.build();

    ProgressEntityWrapper.ProgressListener pListener = 
      percentage -> assertFalse(Float.compare(percentage, 100) > 0);
    httpPost.setEntity(new ProgressEntityWrapper(multipart, pListener));

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

We’ll also add the interface ProgressListener that enables us to observe the upload progress:

我们还将添加接口ProgressListener,使我们能够观察上传进度:

public static interface ProgressListener {
    void progress(float percentage);
}

Here’s our extended version of HttpEntityWrapper, ProgressEntityWrapper“:

这里是我们的HttpEntityWrapper的扩展版本,ProgressEntityWrapper“。

public class ProgressEntityWrapper extends HttpEntityWrapper {
    private ProgressListener listener;

    public ProgressEntityWrapper(HttpEntity entity, ProgressListener listener) {
        super(entity);
        this.listener = listener;
    }

    @Override
    public void writeTo(OutputStream outstream) throws IOException {
        super.writeTo(new CountingOutputStream(outstream, listener, getContentLength()));
    }
}

And here’s the extended version of FilterOutputStream,CountingOutputStream“:

而这里是FilterOutputStream的扩展版本,CountingOutputStream“。

public static class CountingOutputStream extends FilterOutputStream {
    private ProgressListener listener;
    private long transferred;
    private long totalBytes;

    public CountingOutputStream(
      OutputStream out, ProgressListener listener, long totalBytes) {
        super(out);
        this.listener = listener;
        transferred = 0;
        this.totalBytes = totalBytes;
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        out.write(b, off, len);
        transferred += len;
        listener.progress(getCurrentProgress());
    }

    @Override
    public void write(int b) throws IOException {
        out.write(b);
        transferred++;
        listener.progress(getCurrentProgress());
    }

    private float getCurrentProgress() {
        return ((float) transferred / totalBytes) * 100;
    }
}

Note that:

请注意,。

  • When extending FilterOutputStream to “CountingOutputStream,” we’re overriding the write() method to count the written (transferred) bytes
  • When extending HttpEntityWrapper to “ProgressEntityWrapper,” we’re overriding the writeTo() method to use our “CountingOutputStream”

9. Conclusion

9.结论

In this article, we illustrated the most common ways to send POST HTTP Requests with the Apache HttpClient 4.

在这篇文章中,我们说明了用Apache HttpClient 4发送POST HTTP请求的最常见方法。

We learned how to send a POST request with Authorization, how to post using HttpClient fluent API, and how to upload a file and track its progress.

我们学习了如何发送带有授权的POST请求,如何使用HttpClientfluent API发布,以及如何上传文件并跟踪其进度。

The implementation of all these examples and code snippets can be found in the github project.

所有这些例子和代码片段的实现都可以在github项目中找到。