HttpClient系列-Post使用基础知识(三)

栏目: Java · 发布时间: 6年前

内容简介:首先,让我们来看一个简单的例子,并使用HttpClient发送POST请求。我们将使用两个参数 - “username”和“password” 进行POST :接下来,让我们看看如何使用HttpClient对身份验证凭据进行POST 。

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

我们将使用两个参数 - “username”和“password” 进行POST :

@Test
public void test() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("username", "John"));
    params.add(new BasicNameValuePair("password", "pass"));
    httpPost.setEntity(new UrlEncodedFormEntity(params));
 
    HttpPost httpPost = new HttpPost("http://localhost:8080");

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

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

使用授权进行POST

接下来,让我们看看如何使用HttpClient对身份验证凭据进行POST 。

在以下示例中 - 我们通过添加Authorization在Header向使用基本身份验证保护的URL发送POST请求:

@Test
public void test()
  throws ClientProtocolException, IOException, AuthenticationException {
    CloseableHttpClient client = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080");


   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();
}
复制代码

使用JSON POST

现在 - 让我们看看如何使用HttpClient向JSON主体发送POST请求。

在以下示例中 - 我们将一些Person(id,name)作为JSON发送:

@Test
public void test() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080");

    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();
}
复制代码

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

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

使用HttpClient Form进行 POST

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

我们将发送一个带有两个参数“ username ”和“ password ” 的请求:

@Test
public void test() 
  throws ClientProtocolException, IOException {
    HttpResponse response = Request.Post("http://localhost:8080").bodyForm(
      Form.form().add("username", "John").add("password", "pass").build())
      .execute().returnResponse();
 
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
复制代码

POST多参数请求

现在,让我们发一个多参数请求。

我们将使用 MultipartEntityBuilder 发布文件,useranme和password:

@Test
public void whenSendMultipartRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080");

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

复制代码

使用HttpClient上传文件

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

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

@Test
public void test() throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080");

    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();
}
复制代码

获取文件上传 进度

最后 - 让我们看看如何使用HttpClient获取文件上传的进度。

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

首先 - 这是上传方法:

@Test
public void test()
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080");

    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();
}
复制代码

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

public static interface ProgressListener {
    void progress(float percentage);
}
复制代码

这是我们的扩展版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()));
    }
}
复制代码

而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;
    }
}
复制代码

注意:

  • 将FilterOutputStream扩展为 CountingOutputStream 时 -我们重写write()方法来计算写入(传输)的字节数
  • 将HttpEntityWrapper扩展为 ProgressEntityWrapper 时 -我们重写writeTo()方法以使用我们的 CountingOutputStream

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Visual Thinking

Visual Thinking

Colin Ware / Morgan Kaufmann / 2008-4-18 / USD 49.95

Increasingly, designers need to present information in ways that aid their audiences thinking process. Fortunately, results from the relatively new science of human visual perception provide valuable ......一起来看看 《Visual Thinking》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试