首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Apache HttpClient 4.x 發送 POST 請求完整指南:從基礎到文件上傳進度監控

     編輯:Java 綜合教學

Apache HttpClient 4.x 發送 POST 請求完整指南

HttpClient 是 Java 領域最常用的 HTTP 客戶端庫。本文總結 HttpClient 4.x 中各類 POST 請求的典型用法,涵蓋基本表單提交、認證、JSON 傳輸、Fluent API、Multipart 文件上傳及上傳進度監控,供開發快速查閱。

1. 基礎 POST 請求(表單參數)

使用 UrlEncodedFormEntity 封裝鍵值對參數:

@Test
public void basicPost() throws Exception {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("https://www.example.com");
    List<NameValuePair> params = new ArrayList<>();
    params.add(new BasicNameValuePair("username", "John"));
    params.add(new BasicNameValuePair("password", "pass"));
    httpPost.setEntity(new UrlEncodedFormEntity(params));
    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

2. 攜帶 Basic Authentication 的 POST

在 Header 中加入認證信息:

@Test
public void postWithAuth() throws Exception {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("https://www.example.com");
    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();
}

3. 發送 JSON 數據

設置 Content-Type 為 application/json:

@Test
public void postJson() throws Exception {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("https://www.example.com");
    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();
}

4. 使用 Fluent API 簡化調用

鏈式調用,代碼更簡潔:

@Test
public void postFluent() throws Exception {
    HttpResponse response = Request.Post("https://www.example.com")
        .bodyForm(Form.form().add("username", "John").add("password", "pass").build())
        .execute().returnResponse();
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

5. Multipart 請求(混合表單與文件)

使用 MultipartEntityBuilder 構建多部分實體:

@Test
public void postMultipart() throws Exception {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("https://www.example.com");
    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");
    httpPost.setEntity(builder.build());
    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

6. 純文件上傳

僅上傳文件二進制流:

@Test
public void uploadFile() throws Exception {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("https://www.example.com");
    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addBinaryBody("file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");
    httpPost.setEntity(builder.build());
    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

7. 監控文件上傳進度

通過擴展 HttpEntityWrapper 實現進度回調:

// 進度監聽接口
public interface ProgressListener { void progress(float percentage); }

// 包裝實體,寫入時統計已傳輸字節
public class ProgressEntityWrapper extends HttpEntityWrapper {
    private ProgressListener listener;
    public ProgressEntityWrapper(HttpEntity entity, ProgressListener listener) {
        super(entity); this.listener = listener;
    }
    @Override public void writeTo(OutputStream out) throws IOException {
        super.writeTo(new CountingOutputStream(out, listener, getContentLength()));
    }
}

// 計數輸出流
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; 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; }
}

// 使用示例
@Test
public void uploadWithProgress() throws Exception {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("https://www.example.com");
    HttpEntity multipart = MultipartEntityBuilder.create()
        .addBinaryBody("file", new File("test.txt"), ContentType.APPLICATION_OCTET_STREAM, "file.ext")
        .build();
    httpPost.setEntity(new ProgressEntityWrapper(multipart, percentage -> {
        System.out.println("上傳進度: " + percentage + "%");
        assertFalse(Float.compare(percentage, 100) > 0);
    }));
    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

總結

HttpClient 4.x 提供了豐富的 API 滿足各種 POST 場景。實際開發中,建議配合連接池管理客端實例,並妥善關閉響應流以釋放資源。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved