1. 개요

이 예제에서는 HttpClient 4 를 사용하여 먼저 인증을 사용한 후 유창한 HttpClient API를 사용한 POST를 수행합니다 .

마지막으로 HttpClient를 사용하여 파일을 업로드하는 방법에 대해 설명합니다.

2. 기본 POST

먼저 간단한 예제를 살펴보고 HttpClient 를 사용하여 POST 요청을 보냅니다 .

" username "과 " password " 라는 두 개의 매개 변수를 사용하여 POST를 수행합니다 .

@Test
public void whenSendPostRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    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();
}

POST 요청에 매개변수를 포함하기 위해 NameValuePair List어떻게 사용했는지 확인하십시오 .

3. 인증 후 POST

다음으로 HttpClient 를 사용하여 인증 자격 증명으로 POST를 수행하는 방법을 살펴보겠습니다 .

다음 예에서는 Authorization 헤더를 추가하여 기본 인증으로 보호되는 URL에 POST 요청을 보냅니다.

@Test
public void whenSendPostRequestWithAuthorizationUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException, AuthenticationException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://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();
}

4. JSON으로 게시

이제 HttpClient 를 사용하여 JSON 본문과 함께 POST 요청을 보내는 방법을 살펴보겠습니다 .

다음 예에서는 개인 정보( id, name )를 JSON으로 전송합니다.

@Test
public void whenPostJsonUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://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();
}

StringEntity 를 사용하여 요청 본문을 설정하는 방법에 유의하십시오 .

또한 ContentType 헤더를 application/json 으로 설정하여 우리가 보내는 콘텐츠의 표현에 대한 필요한 정보를 서버에 제공합니다.

5. HttpClient Fluent API를 사용한 POST

다음으로 HttpClient Fluent API 를 사용하여 POST를 수행해 보겠습니다 .

" username "과 " password " 라는 두 개의 매개변수를 사용하여 요청을 보냅니다 .

@Test
public void whenPostFormUsingHttpClientFluentAPI_thenCorrect() 
  throws ClientProtocolException, IOException {
    HttpResponse response = Request.Post("http://www.example.com").bodyForm(
      Form.form().add("username", "John").add("password", "pass").build())
      .execute().returnResponse();

    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

6. POST 멀티파트 요청

이제 멀티파트 요청을 게시해 보겠습니다.

MultipartEntityBuilder 를 사용하여 File , 사용자 이름 및 암호를 게시합니다 .

@Test
public void whenSendMultipartRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://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");

    HttpEntity multipart = builder.build();
    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();
}

7. HttpClient 를 사용 하여 파일 업로드

다음으로 HttpClient 를 사용하여 파일 을 업로드하는 방법을 살펴보겠습니다 .

MultipartEntityBuilder 를 사용하여 " test.txt " 파일을 업로드합니다 .

@Test
public void whenUploadFileUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

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

8. 파일 업로드 진행률 가져오기

마지막으로 HttpClient 를 사용하여 파일 업로드 진행 상황을 확인하는 방법을 살펴보겠습니다 .

다음 예제에서는 HttpEntityWrapper 를 확장하여 업로드 프로세스에 대한 가시성을 얻습니다.

먼저 업로드 방법은 다음과 같습니다.

@Test
public void whenGetUploadFileProgressUsingHttpClient_thenCorrect()
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    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 "로 확장할 때 "CountingOutputStream" 을 사용하도록 writeTo() 메서드를 재정의합니다 .

9. 결론

이 기사에서는 Apache HttpClient 4 를 사용하여 POST HTTP 요청을 보내는 가장 일반적인 방법을 설명했습니다 .

Authorization과 함께 POST 요청을 보내는 방법, HttpClient 흐름 API를 사용하여 게시하는 방법, 파일을 업로드하고 진행 상황을 추적하는 방법을 배웠습니다.

이러한 모든 예제와 코드 스니펫의 구현은 github 프로젝트 에서 찾을 수 있습니다 .

HTTPClient footer