發出 HTTP(S) 要求

本頁說明如何透過 App Engine 應用程式發出 HTTP(S) 要求。

Java 8 執行階段 與 Java 7 行為的比較

在預設情況下,在 Java 8 執行階段中執行的應用程式是使用標準的 Java 類別,例如 java.net.HttpURLConnection 用於 HTTP(S) 要求。您可以像發送任何其他 Java 應用程式一樣發送要求。

當您的應用程式使用預設行為執行於 Java 8 時,您必須在應用程式啟用計費,否則您將會遇到以下異常狀況:

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

儘管需要在應用程式啟用計費,但您的應用程式產生的費用不會比在 Java 7 上執行相同應用程式更高。

在已淘汰的 Java 7 執行階段中執行的應用程式也使用標準 Java 類別,例如 java.net.HttpURLConnection。然而在 Java 7 執行階段中,這個呼叫實際上是由 URL Fetch 服務處理的。Java 7 應用程式可以選擇使用 App Engine URL Fetch API 直接使用 URL Fetch 服務,而不是標準的 Java 調用。

使用標準 Java 8 執行階段網路類別

若您在 Java 8 執行階段中使用標準 Java 網路類別,則您的應用程式將可以存取以下功能:

在 Java 8 應用程式中使用 URL Fetch

若您必須在 Java 8 應用程式中使用 URL Fetch,請將以下行新增至 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() 方法,以擷取網址中的內容:

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 Fetch,您可以在 appengine-web.xml 檔案中使用 appengine.api.urlfetch.defaultDeadline 設定調整預設的要求截止時間。

設定標頭

若您正在使用 URL Fetch,您可以呼叫您 HttpURLConnection 物件的 setRequestProperty() 方法,在外送要求上設定 HTTP 標頭。以下的程式碼片端將 X-MyApp-Version 標頭設定為 2.7.3

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

停用重新導向

在預設情況下,HttpURLConnection 會追蹤 HTTP 重新導向。若您使用 URL Fetch,則基礎 URL Fetch 將追蹤重新導向最多五次。若要停用此行為,將 false 值傳傳送至 HttpURLConnection 物件的 setInstanceFollowRedirects() 方法:

conn.setInstanceFollowRedirects(false);

若您的應用程式未使用 java.net,而是直接使用基礎 urlfetch 套件,您的應用程式必須指定 doNotFollowRedirects

發出 HTTPS 要求

若您使用 URL Fetch,請使用 urlfetch 套件中的 FetchOptions 類別,並呼叫 validateCertificate()

發出非同步要求

HTTP(S) 要求預設為同步。若要發出非同步要求,您的應用程式必須使用 URLFetchService fetchAsync() 方法。此方法會傳回 java.util.concurrent.Future<HTTPResponse>

發出要求至其他 App Engine 應用程式

發出要求至其他 App Engine 應用程式時,App Engine 應用程式必須在要求中加入 X-Appengine-Inbound-Appid 標頭以表明自己的身分。如果您指示 URL Fetch 服務不要追蹤重新導向,App Engine 會自動在要求中加入這個標頭。有關停用重新導向的資訊,請參閱停用重新導向

後續步驟

如要瞭解網址擷取服務,例如透過網址擷取要求傳送的標頭,請參閱傳出要求一文。

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Java 8 適用的 App Engine 標準環境