您的位置 首页 java

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

简述

本文学习如何简单的使用POST,如何上传文件等等场景

基础POST

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

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

@Test
public void test() 
 throws ClientProtocolException, IOException {
  close ableHttpClient 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("");
 CloseableHttpResponse response = client.execute(httpPost);
 assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
 client.close();
}
 

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

使用授权进行POST

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

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

@Test
public void test()
 throws ClientProtocolException, IOException, AuthenticationException {
 CloseableHttpClient client = HttpClients.createDefault();
 HttpPost httpPost = new HttpPost("");
 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("");
 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("").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(“”);

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

小结

HttpClient的基础知识到本文就已经介绍结束,希望对你有所收获。

文章来源:智云一二三科技

文章标题:HttpClient系列-Post使用基础知识(三)

文章地址:https://www.zhihuclub.com/186963.shtml

关于作者: 智云科技

热门文章

网站地图