簡(jiǎn)述
本文學(xué)習(xí)如何簡(jiǎn)單的使用POST,如何上傳文件等等場(chǎng)景
基礎(chǔ)POST
首先,讓我們來看一個(gè)簡(jiǎn)單的例子,并使用HttpClient發(fā)送POST請(qǐng)求。
我們將使用兩個(gè)參數(shù) - “username”和“password” 進(jìn)行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();
}
請(qǐng)注意我們?nèi)绾问褂肔ist<NameValuePair>在POST請(qǐng)求中包含參數(shù)。
使用授權(quán)進(jìn)行POST
接下來,讓我們看看如何使用HttpClient對(duì)身份驗(yàn)證憑據(jù)進(jìn)行POST 。
在以下示例中 - 我們通過添加Authorization在Header向使用基本身份驗(yàn)證保護(hù)的URL發(fā)送POST請(qǐng)求:
@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
現(xiàn)在 - 讓我們看看如何使用HttpClient向JSON主體發(fā)送POST請(qǐng)求。
在以下示例中 - 我們將一些Person(id,name)作為JSON發(fā)送:
@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();
}
注意我們?nèi)绾问褂?code>StringEntity來設(shè)置請(qǐng)求的主體。
我們還將ContentType標(biāo)頭設(shè)置為application / json ,以便為服務(wù)器提供有關(guān)我們發(fā)送的內(nèi)容表示的必要信息。
使用HttpClient Form進(jìn)行 POST
接下來,讓我們使用HttpClient Fluent API進(jìn)行POST 。
我們將發(fā)送一個(gè)帶有兩個(gè)參數(shù)“ username ”和“ password ” 的請(qǐng)求:
@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多參數(shù)請(qǐng)求
現(xiàn)在,讓我們發(fā)一個(gè)多參數(shù)請(qǐng)求。
我們將使用MultipartEntityBuilder發(fā)布文件,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();
}
獲取文件上傳 進(jìn)度
最后 - 讓我們看看如何使用HttpClient獲取文件上傳的進(jìn)度。
在下面的示例中,我們將擴(kuò)展HttpEntityWrapper以獲得對(duì)上載過程的可見性。
首先 - 這是上傳方法:
@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,使我們能夠觀察上傳進(jìn)度:
public static interface ProgressListener {
void progress(float percentage);
}
這是我們的擴(kuò)展版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的擴(kuò)展版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擴(kuò)展為
CountingOutputStream時(shí) -我們重寫write()方法來計(jì)算寫入(傳輸)的字節(jié)數(shù) - 將HttpEntityWrapper擴(kuò)展為
ProgressEntityWrapper時(shí) -我們重寫writeTo()方法以使用我們的CountingOutputStream
小結(jié)
HttpClient的基礎(chǔ)知識(shí)到本文就已經(jīng)介紹結(jié)束,希望對(duì)你有所收獲。