Перейти к основному содержимому

Публикация с помощью Apache HttpClient

· 5 мин. чтения

Упражнение: Сложение двух чисел

Даны два неотрицательный целых числа в виде непустых связных списков. Их цифры хранятся в обратном порядке. И каждый елемент списка содержить ровно одну цифру. Сложите эти два числа и верните сумму в виде связного списка ...

ANDROMEDA

1. Обзор

В этом руководстве мы выполним POST с помощью HttpClient 4 , сначала используя авторизацию, а затем свободный API HttpClient.

Наконец, мы обсудим, как загрузить файл с помощью HttpClient.

2. Базовый ПОСТ

Во-первых, давайте рассмотрим простой пример и отправим POST-запрос с помощью HttpClient .

Мы сделаем 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();
}

Обратите внимание, как мы использовали список NameValuePair для включения параметров в запрос POST.

3. POST с авторизацией

Далее давайте посмотрим, как выполнить POST с учетными данными аутентификации с помощью HttpClient .

В следующем примере мы отправим запрос POST на URL-адрес, защищенный с помощью базовой аутентификации, добавив заголовок авторизации:

@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

Теперь давайте посмотрим, как отправить запрос POST с телом JSON с помощью HttpClient .

В следующем примере мы отправим некоторую информацию о человеке ( 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. POST с HttpClient Fluent API

Затем выполним POST с помощью HttpClient Fluent API.

Мы отправим запрос с двумя параметрами, « имя пользователя » и « пароль »:

@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

Теперь давайте отправим составной запрос.

Мы опубликуем File , имя пользователя и пароль, используя MultipartEntityBuilder :

@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.

Мы загрузим файл « test.txt » с помощью MultipartEntityBuilder :

@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» мы переопределяем метод writeTo() для использования нашего «CountingOutputStream» .

9. Заключение

В этой статье мы проиллюстрировали наиболее распространенные способы отправки HTTP-запросов POST с помощью Apache HttpClient 4 .

Мы узнали, как отправлять POST-запросы с авторизацией, как публиковать с помощью HttpClient Fluent API, а также как загружать файл и отслеживать его ход.

Реализацию всех этих примеров и фрагментов кода можно найти в проекте github .