HTTP(S) リクエストの発行

このページでは、App Engine アプリから HTTP(S) リクエストを発行する方法について説明します。

Java 8 ランタイムと Java 7 の動作

Java 8 ランタイムで稼働するアプリケーションは、デフォルトでは java.net.HttpURLConnection などの標準 Java クラスを使用して HTTP(S) リクエストを発行します。他の Java アプリケーションの場合と同じようにリクエストを送信します。

デフォルトの動作を使用して Java 8 でアプリケーションを実行する場合、アプリケーションを課金対象にする必要があります。そうしないと、次の例外が発生します。

  • java.net.UnknownHostException
  • java.net.SocketTimeoutException
  • java.io.IOException

アプリケーションを課金対象にする必要がありますが、Java 7 で実行される同じアプリケーション以上のコストが発生することはありません。

非推奨の Java 7 ランタイムで稼働するアプリケーションでも、java.net.HttpURLConnection などの標準 Java クラスを使用して呼び出しを行います。ただし、Java 7 ランタイムでは、そのような呼び出しは実際には URL 取得サービスによって処理されます。標準 Java 呼び出しの代わりに、Java 7 のアプリケーションには App Engine の URL Fetch API を使用して URL 取得サービスを直接使用するオプションがあります。

標準の Java 8 ランタイム ネットワーク クラスの使用

Java 8 ランタイムで標準 Java ネットワーク クラスを使用すると、アプリに次のメリットがあります。

  • リクエスト データに設定されている 32 MB の制限がなくなります。
  • HTTP 2.0 をサポートします。
  • Java 用 Google Cloud クライアント ライブラリからアクセス可能な Google Cloud ベースの API をすべてサポートしています。

Java 8 アプリケーションでの URL 取得の使用

Java 8 アプリで URL 取得を使用する場合は、appengine-web.xml に次の行を追加します。

 <url-stream-handler>urlfetch</url-stream-handler>

例:

<xml version="1.0" encoding="utf-8">
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <!-- ... -->
  <url-stream-handler>urlfetch</url-stream-handler>
  <!-- ... -->
</appengine-web-app>

この設定を使用する場合は、課金対象にする必要はありません。

HTTP リクエストの発行

送信 HTTP リクエストを発行するには、java.net.URLConnection を使用します。

次のスニペットは基本 HTTP GET リクエストを実行する方法を示しています。アプリケーションは新しい URL オブジェクトを作成し、次にオブジェクトの openStream() メソッドを呼び出して、その URL にあるコンテンツを取得します。

Java 8

URL url = new URL("http://api.icndb.com/jokes/random");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer json = new StringBuffer();
String line;

while ((line = reader.readLine()) != null) {
  json.append(line);
}
reader.close();

Java 7

URL url = new URL("http://api.icndb.com/jokes/random");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer json = new StringBuffer();
String line;

while ((line = reader.readLine()) != null) {
  json.append(line);
}
reader.close();

より高度なリクエストの場合は、次のように java.net.HttpURLConnection を使用します。

  1. 新しい URL オブジェクトを作成します。
  2. URL オブジェクトの openConnection() メソッドを呼び出して、新しい URLConnection オブジェクトを作成します。
  3. URLConnection オブジェクトを HttpURLConnection オブジェクト タイプにキャストして、新しい HttpURLConnection オブジェクトを作成します。
  4. HttpURLConnection オブジェクトのリクエスト メソッドを設定します。
  5. リクエストの出力ストリームを作成します。
  6. リクエストのペイロードをストリームに書き込みます。
  7. ストリームを閉じます。

次のスニペットでは、HttpURLConnection を使用して、より高度なリクエストを実行し、PUT リクエストを介してウェブ形式からデータを送信します。

Java 8

URL url = new URL("http://jsonplaceholder.typicode.com/posts/" + id);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Enable output for the connection.
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("Accept", "application/json");
// Set HTTP request method.
conn.setRequestMethod("PUT");

// Create JSON request.
JSONObject jsonObj =
    new JSONObject().put("userId", 1).put("id", id).put("title", text).put("body", text);

OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(jsonObj.toString());
writer.close();

int respCode = conn.getResponseCode(); // New items get NOT_FOUND on PUT
if (respCode == HttpURLConnection.HTTP_OK || respCode == HttpURLConnection.HTTP_NOT_FOUND) {
  req.setAttribute("error", "");
  StringBuilder response = new StringBuilder();
  String line;

  // Read input data stream.
  BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  while ((line = reader.readLine()) != null) {
    response.append(line);
  }
  reader.close();
  req.setAttribute("response", response.toString());
} else {
  req.setAttribute("error", conn.getResponseCode() + " " + conn.getResponseMessage());
}

Java 7

URL url = new URL("http://jsonplaceholder.typicode.com/posts/" + id);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("PUT");

OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(URLEncoder.encode(jsonObj.toString(), "UTF-8"));
writer.close();

int respCode = conn.getResponseCode();  // New items get NOT_FOUND on PUT
if (respCode == HttpURLConnection.HTTP_OK || respCode == HttpURLConnection.HTTP_NOT_FOUND) {
  req.setAttribute("error", "");
  StringBuffer response = new StringBuffer();
  String line;

  BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  while ((line = reader.readLine()) != null) {
    response.append(line);
  }
  reader.close();
  req.setAttribute("response", response.toString());
} else {
  req.setAttribute("error", conn.getResponseCode() + " " + conn.getResponseMessage());
}

リクエストのタイムアウトの設定

URL 取得を使用する場合、appengine-web.xml ファイル内の appengine.api.urlfetch.defaultDeadline 設定を使用してリクエストのデフォルト期限を調整できます。

ヘッダーの設定

URL 取得を使用している場合は、HttpURLConnection オブジェクトの setRequestProperty() メソッドを呼び出すことで、発信リクエストに HTTP ヘッダーを設定できます。次のスニペットは X-MyApp-Version ヘッダーを 2.7.3 に設定します。

conn.setRequestProperty("X-MyApp-Version", "2.7.3");

リダイレクトの無効化

デフォルトで HttpURLConnection は HTTP リダイレクトに従います。URL 取得を使用している場合は、基になっている URL 取得サービスは最大 5 回のリダイレクトに追随します。この動作を無効にするには、HttpURLConnection オブジェクトの setInstanceFollowRedirects() メソッドに値 false を渡します。

conn.setInstanceFollowRedirects(false);

java.net ではなく基になっている urlfetch パッケージをアプリで直接使用する場合は、アプリで doNotFollowRedirects を指定する必要があります。

HTTPS リクエストの発行

URL 取得を使用している場合は、urlfetch パッケージの FetchOptions クラスを使用して HTTPS リクエストを発行し、validateCertificate() を呼び出します。

非同期リクエストの発行

HTTP(S) リクエストはデフォルトで同期されます。非同期リクエストを発行するには、アプリケーションで URLFetchService fetchAsync() メソッドを使用する必要があります。このメソッドは java.util.concurrent.Future<HTTPResponse> を返します。

別の App Engine アプリへのリクエストの発行

別の App Engine アプリにリクエストを発行する場合、App Engine アプリでリクエストに X-Appengine-Inbound-Appid ヘッダーを追加して、その ID を表明する必要があります。URL 取得サービスにリダイレクトに従わないように指示した場合、App Engine によって、自動的にこのヘッダーがリクエストに追加されます。リダイレクトの無効化に関するガイダンスについては、リダイレクトの無効化を参照してください。

次のステップ

送信リクエスト内の URL 取得リクエストで送信されるヘッダーなど、URL 取得サービスについて学習する。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Java 8 の App Engine スタンダード環境