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

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

内容简介:首先,让我们来看一个简单的例子,并使用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

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

查看所有标签

猜你喜欢:

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

JavaScript编程精解

JavaScript编程精解

Marijn Haverbeke / 徐涛 / 机械工业出版社华章公司 / 2012-10-1 / 49.00元

如果你只想阅读一本关于JavaScript的图书,那么本书应该是你的首选。本书由世界级JavaScript程序员撰写,JavaScript之父和多位JavaScript专家鼎力推荐。本书适合作为系统学习JavaScript的参考书,它在写作思路上几乎与现有的所有同类书都不同,打破常规,将编程原理与运用规则完美地结合在一起,而且将所有知识点与一个又一个经典的编程故事融合在一起,读者可以在轻松的游戏式......一起来看看 《JavaScript编程精解》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具