发出 HTTP(S) 请求

区域 ID

REGION_ID 是 Google 根据您在创建应用时选择的区域分配的缩写代码。此代码不对应于国家/地区或省,尽管某些区域 ID 可能类似于常用国家/地区代码和省代码。对于 2020 年 2 月以后创建的应用,REGION_ID.r 包含在 App Engine 网址中。对于在此日期之前创建的现有应用,网址中的区域 ID 是可选的。

详细了解区域 ID

本页介绍如何从 App Engine 应用发出 HTTP(S) 请求。

默认情况下,在 Java 8 运行时中运行的应用使用标准 Java 类(例如 java.net.HttpURLConnection)来发出 HTTP(S) 请求。您可以像为任何其他 Java 应用一样发送请求。如需使用默认行为,您必须为应用启用结算功能,否则会出现以下异常:

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

使用标准运行时环境网络类

如果您使用标准 Java 网络类,则应用可以使用以下功能:

使用网址提取

如果您必须在 Java 8 应用中使用网址提取,请将以下行添加到 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 请求

您可以使用 java.net.URLConnection 发出出站 HTTP 请求。

以下代码段演示了如何执行基本 HTTP GET 请求。 应用创建新的 URL 对象,然后调用该对象的 openStream() 方法来检索该网址中的内容:

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 请求从网络表单提交数据:

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

设置请求超时

如果您使用 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 服务最多遵循五个重定向。这些重定向可能会将敏感信息(如授权标头)转发到重定向的目的地。如果应用不需要 HTTP 重定向,则建议您停用重定向。

如需停用此行为,请将值 false 传递到 HttpURLConnection 对象的 setInstanceFollowRedirects() 方法:

conn.setInstanceFollowRedirects(false);

如果应用直接使用底层 urlfetch 软件包而不是 java.net,则应用必须指定 doNotFollowRedirects

发出 HTTPS 请求

如果您使用 URL Fetch,请使用 urlfetch 软件包中的 FetchOptions 类发出 HTTPS 请求,然后调用 validateCertificate()

发出异步请求

HTTP(S) 请求默认为同步请求。如需发出异步请求,您的应用必须使用 URLFetchServicefetchAsync() 方法。此方法会返回 java.util.concurrent.Future<HTTPResponse>

向其他 App Engine 应用发出请求

向其他 App Engine 应用发出请求时,您的 App Engine 应用必须通过将标头 X-Appengine-Inbound-Appid 添加到请求中来声明其身份。如果您指示 URL Fetch 服务不遵循重定向,则 App Engine 会自动将此标头添加到请求中。

如需有关如何停用重定向的指导,请参阅停用重定向

后续步骤

参阅出站请求了解 URL Fetch 服务,例如在 URL Fetch 请求中发送的标头。