{空}[sc name =” httpclient__start”]


1概要

この記事では、Apache


HttpClient


ライブラリーの高度な使い方を見ていきます。

HTTPリクエストにカスタムヘッダを追加する例を見てみましょう。また、プロキシサーバを介してリクエストを承認して送信するようにクライアントを設定する方法を説明します。

HTTPサーバーをスタブ化するためにWiremockを使用します。 Wiremockについてもっと知りたいなら、

この記事

をチェックしてください。


2カスタム

User-Agent

ヘッダーを持つHTTPリクエスト

HTTP GETリクエストにカスタムの

User-Agent

ヘッダーを追加したいとしましょう。

User-Agent

ヘッダーには、ネットワークプロトコルピアが要求元のソフトウェアユーザーエージェントのアプリケーションタイプ、オペレーティングシステム、およびソフトウェアベンダまたはソフトウェアバージョンを識別できるようにする特性文字列が含まれています。

HTTPクライアントを書き始める前に、埋め込みモックサーバーを起動する必要があります。

@Rule
public WireMockRule serviceMock = new WireMockRule(8089);


HttpGet

インスタンスを作成するときには、単に

setHeader()

メソッドを使用して、ヘッダーの名前と値を渡すことができます。そのヘッダはHTTPリクエストに追加されます。

String userAgent = "BaeldungAgent/1.0";
HttpClient httpClient = HttpClients.createDefault();

HttpGet httpGet = new HttpGet("http://localhost:8089/detail");
httpGet.setHeader(HttpHeaders.USER__AGENT, userAgent);

HttpResponse response = httpClient.execute(httpGet);

assertEquals(response.getStatusLine().getStatusCode(), 200);


User-Agent

ヘッダーを追加し、その要求を

execute()

メソッドを介して送信します。

「BaeldungAgent/1.0」に等しい値を持つヘッダ

User-Agent

を持つURL

/detail

に対してGETリクエストが送信されると、

serviceMock

は200のHTTPレスポンスコードを返します。

serviceMock.stubFor(get(urlEqualTo("/detail"))
  .withHeader("User-Agent", equalTo(userAgent))
  .willReturn(aResponse().withStatus(200)));


3 POSTリクエストボディにデータを送信する

通常、HTTP POSTメソッドを実行しているときは、エンティティをリクエストボディとして渡します。

HttpPost

オブジェクトのインスタンスを作成するとき、

setEntity()

メソッドを使用してそのリクエストにボディを追加できます。

String xmlBody = "<xml><id>1</id></xml>";
HttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://localhost:8089/person");
httpPost.setHeader("Content-Type", "application/xml");

StringEntity xmlEntity = new StringEntity(xmlBody);
httpPost.setEntity(xmlEntity);

HttpResponse response = httpClient.execute(httpPost);

assertEquals(response.getStatusLine().getStatusCode(), 200);


XML

形式の本文を使用して

StringEntity

インスタンスを作成しています。送信するコンテンツの種類に関する情報をサーバーに渡すには、

Content-Type

ヘッダーを ”

application/xml

“に設定することが重要です。

serviceMock

がXML本文を含むPOSTリクエストを受け取ると、ステータスコード200 OKで応答します。

serviceMock.stubFor(post(urlEqualTo("/person"))
  .withHeader("Content-Type", equalTo("application/xml"))
  .withRequestBody(equalTo(xmlBody))
  .willReturn(aResponse().withStatus(200)));


4プロキシサーバー経由でリクエストを送信する

多くの場合、私たちのWebサービスは、追加のロジックを実行し、静的リソースなどをキャッシュするプロキシサーバーの背後にあることがあります。HTTPクライアントを作成して実際のサービスに要求を送信するときすべてのHTTPリクエストでそれが起こります。

このシナリオをテストするには、別の内蔵Webサーバーを起動する必要があります。

@Rule
public WireMockRule proxyMock = new WireMockRule(8090);

2台の組み込みサーバーでは、最初の実際のサービスは8089ポート上にあり、プロキシサーバーは8090ポート上で待機しています。


HttpHost

インスタンスプロキシを引数に取る

DefaultProxyRoutePlanner

を作成して、すべてのリクエストをプロキシ経由で送信するように

HttpClient

を設定します。

HttpHost proxy = new HttpHost("localhost", 8090);
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
HttpClient httpclient = HttpClients.custom()
  .setRoutePlanner(routePlanner)
  .build();

私たちのプロキシサーバーは、8090ポートで待機する実際のサービスにすべての要求をリダイレクトしています。テストの最後に、リクエストがプロキシ経由で実際のサービスに送信されたことを確認します。

proxyMock.stubFor(get(urlMatching(".** "))
  .willReturn(aResponse().proxiedFrom("http://localhost:8089/")));

serviceMock.stubFor(get(urlEqualTo("/private"))
  .willReturn(aResponse().withStatus(200)));

assertEquals(response.getStatusLine().getStatusCode(), 200);
proxyMock.verify(getRequestedFor(urlEqualTo("/private")));
serviceMock.verify(getRequestedFor(urlEqualTo("/private")));


5プロキシ経由で認証するためのHTTPクライアントの設定

前の例を拡張して、許可を実行するためにプロキシサーバーが使用される場合がいくつかあります。このような構成では、プロキシはすべての要求を承認し、それらをプロキシの背後に隠れているサーバーに渡すことができます。

認証プロセスを実行するために使用される

Authorization

ヘッダーと共に、プロキシ経由で各要求を送信するようにHttpClientを構成できます。

1人のユーザーのみを認証するプロキシサーバーがあるとします。 ”

username

admin





、パスワード ”

secret

password



.

プロキシ経由で承認されるユーザーの資格情報を使用して

BasicCredentialsProvider

インスタンスを作成する必要があります。

HttpClient

が自動的に適切な値で

Authorization

ヘッダーを追加するようにするには、提供された認証情報と認証情報を格納する

BasicAuthCache

を持​​つ

HttpClientContext

を作成する必要があります。

HttpHost proxy = new HttpHost("localhost", 8090);
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
//Client credentials
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(proxy),
  new UsernamePasswordCredentials("username__admin", "secret__password"));
//Create AuthCache instance
AuthCache authCache = new BasicAuthCache();

BasicScheme basicAuth = new BasicScheme();
authCache.put(proxy, basicAuth);
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credentialsProvider);
context.setAuthCache(authCache);

HttpClient httpclient = HttpClients.custom()
  .setRoutePlanner(routePlanner)
  .setDefaultCredentialsProvider(credentialsProvider)
  .build();


HttpClientを設定すると、

サービスへのリクエストを行うと、認証プロセスを実行するために

Authorization

ヘッダーを持つリクエストをプロキシ経由で送信します。各リクエストに自動的に設定されます。

実際にサービスへのリクエストを実行しましょう:

HttpGet httpGet = new HttpGet("http://localhost:8089/private");
HttpResponse response = httpclient.execute(httpGet, context);

設定で

httpClient



execute()

メソッドを検証することで、リクエストが

Authorization

ヘッダーを持つプロキシを経由したことを確認します。

proxyMock.stubFor(get(urlMatching("/private"))
  .willReturn(aResponse().proxiedFrom("http://localhost:8089/")));
serviceMock.stubFor(get(urlEqualTo("/private"))
  .willReturn(aResponse().withStatus(200)));

assertEquals(response.getStatusLine().getStatusCode(), 200);
proxyMock.verify(getRequestedFor(urlEqualTo("/private"))
  .withHeader("Authorization", containing("Basic")));
serviceMock.verify(getRequestedFor(urlEqualTo("/private")));


6. 結論

この記事では、高度なHTTP呼び出しを実行するためにApache

HttpClient

を設定する方法を説明します。プロキシサーバー経由でリクエストを送信する方法と、プロキシ経由で承認する方法を見ました。

これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/httpclient[GitHubプロジェクト]にあります。そのまま実行します。

{空}[sc name =” httpclient__end”]