Emite solicitudes HTTP(S)

En esta página, se describe cómo emitir solicitudes HTTP(S) desde tu app de App Engine.

Comparación entre el entorno de ejecución de Java 8 y el de Java 7

Las aplicaciones que se ejecutan en el entorno de ejecución de Java 8 de manera predeterminada usan clases estándar de Java, como java.net.HttpURLConnection para solicitudes HTTP(S). Las solicitudes se envían como con cualquier otra aplicación de Java.

Cuando tu app se ejecuta en Java 8 con el comportamiento predeterminado, debes habilitar la facturación para tu aplicación; así evitarás las siguientes excepciones:

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

A pesar del requerimiento para habilitar la facturación de tu aplicación, esta no incurrirá en mayores gastos que la misma aplicación que se ejecuta en Java 7.

Las aplicaciones que se ejecutan en el entorno de ejecución obsoleto de Java 7 también hacen llamadas mediante clases estándar de Java, como java.net.HttpURLConnection. Sin embargo, en el entorno de ejecución de Java 7, a esas llamadas las maneja el servicio de recuperación de URL. En lugar de las llamadas estándar de Java, las aplicaciones para Java 7 tienen la opción de usar la API de recuperación de URL de App Engine para utilizar directamente el servicio de recuperación de URL.

Cómo usar las clases de red estándar del entorno de ejecución de Java 8

Si usas las clases de red estándar de Java en el entorno de ejecución de Java 8, tu app tendrá acceso a las siguientes características:

Uso de URLFetch en una aplicación de Java 8

Si tienes que usar la recuperación de URL en una aplicación de Java 8, agrega la siguiente línea a tu archivo appengine-web.xml:

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

Por ejemplo:

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

Ten en cuenta que con esta configuración no se requiere que la aplicación esté habilitada para la facturación.

Emite una solicitud HTTP

Se emite una solicitud HTTP saliente a través de java.net.URLConnection.

En el fragmento siguiente se muestra cómo realizar una solicitud HTTP GET básica. La aplicación crea un nuevo objeto URL y luego llama el método openStream() del objeto para recuperar el contenido en esa 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();

Para solicitudes más avanzadas, usa java.net.HttpURLConnection, como se indica a continuación:

  1. Crea un objeto URL nuevo.
  2. Crea un objeto URLConnection nuevo llamando al método openConnection() de tu objeto URL.
  3. Crea un objeto HttpURLConnection nuevo convirtiendo el objeto URLConnection al tipo de objeto HttpURLConnection.
  4. Configura el método de solicitud del objeto HttpURLConnection.
  5. Crea un flujo de salida para la solicitud.
  6. Escribe la carga útil de la solicitud en el flujo.
  7. Cierra el flujo

En el fragmento siguiente se muestra cómo usar HttpURLConnection para realizar una solicitud más avanzada enviando datos desde un formulario web a través de una solicitud 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());
}

Cómo configurar un tiempo de espera para las solicitudes

Si usas la recuperación de URL, puedes ajustar el plazo predeterminado para las solicitudes mediante la configuración appengine.api.urlfetch.defaultDeadline en el archivo appengine-web.xml.

Configura los encabezados

Si usas la recuperación de URL, puedes configurar un encabezado HTTP en la solicitud saliente llamando al método setRequestProperty() del objeto HttpURLConnection. En el siguiente fragmento se asigna al encabezado X-MyApp-Version el valor 2.7.3:

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

Inhabilita los redireccionamientos

De manera predeterminada, HttpURLConnection sigue los redireccionamientos HTTP. Si usas la recuperación de URL, el servicio de recuperación de URL subyacente seguirá hasta cinco redireccionamientos. Para inhabilitar este comportamiento, pasa el valor false al método setInstanceFollowRedirects() de tu objeto HttpURLConnection:

conn.setInstanceFollowRedirects(false);

Si tu aplicación usa el paquete urlfetch subyacente de manera directa, en lugar de java.net, deberás especificar doNotFollowRedirects.

Cómo emitir una solicitud HTTPS

Si usas la recuperación de URL, debes emitir una solicitud HTTPS con la clase FetchOptions en el paquete urlfetch y llamar a validateCertificate().

Emite una solicitud asíncrona

Las solicitudes HTTP(S) son síncronas de manera predeterminada. Para emitir una solicitud asíncrona, tu aplicación debe usar el método fetchAsync() de URLFetchService. Este método muestra java.util.concurrent.Future<HTTPResponse>.

Emite una solicitud a otra app de App Engine

Cuando se emite una solicitud a otra app de App Engine, la tuya debe agregar el encabezado X-Appengine-Inbound-Appid a la solicitud para afirmar su identidad. Si le indicas al servicio de recuperación de URL que no siga redireccionamientos, App Engine agregará este encabezado a solicitudes de forma automática. Consulta Inhabilita redireccionamientos para obtener más orientación.

Próximos pasos

En Solicitudes de salida, obtén más información sobre el servicio de recuperación de URL, como los encabezados que se envían en una solicitud de recuperación de URL.

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Entorno estándar de App Engine para Java 8