本文學習如何簡單的使用POST,如何上傳文件等等場景json
首先,讓咱們來看一個簡單的例子,並使用HttpClient發送POST請求。bash
咱們將使用兩個參數 - 「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請求中包含參數。app
接下來,讓咱們看看如何使用HttpClient對身份驗證憑據進行POST 。ide
在如下示例中 - 咱們經過添加Authorization在Header向使用基自己份驗證保護的URL發送POST請求: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();
}
複製代碼
如今 - 讓咱們看看如何使用HttpClient向JSON主體發送POST請求。學習
在如下示例中 - 咱們將一些Person(id,name)做爲JSON發送:ui
@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
來設置請求的主體。this
咱們還將ContentType標頭設置爲application / json
,以便爲服務器提供有關咱們發送的內容表示的必要信息。spa
接下來,讓咱們使用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));
}
複製代碼
如今,讓咱們發一個多參數請求。
咱們將使用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上傳文件。
咱們將使用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;
}
}
複製代碼
注意:
CountingOutputStream
時 -咱們重寫write()方法來計算寫入(傳輸)的字節數ProgressEntityWrapper
時 -咱們重寫writeTo()方法以使用咱們的CountingOutputStream
HttpClient的基礎知識到本文就已經介紹結束,但願對你有所收穫。