Emitir solicitudes HTTP(S)

Esta página describe cómo emitir solicitudes HTTP(S) desde tu aplicación de App Engine.

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

Las aplicaciones que se ejecutan en el entorno de ejecución de Java 8 de manera predeterminada usan las 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 anterior, tu aplicación no costará más que si se ejecutara en Java 7.

Las aplicaciones que funcionan 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.

Cómo emitir una solicitud HTTP

Usa java.net.URLConnection para emitir una solicitud HTTP saliente.

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

Usa java.net.HttpURLConnection para realizar solicitudes más avanzadas 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", "");
  StringBuffer response = new StringBuffer();
  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 app usa el paquete urlfetch subyacente de manera directa en lugar de java.net, deberá especificar doNotFollowRedirects.

Cómo emitir una solicitud HTTPS

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

Cómo emitir una solicitud asíncrona

De manera predeterminada, las solicitudes HTTP(S) son síncronas. 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>.

Cómo emitir una solicitud dirigida a otra aplicación de App Engine

Al emitir una solicitud dirigida a otra aplicación de App Engine, tu aplicación de App Engine debe declarar su identidad agregando el encabezado X-Appengine-Inbound-Appid a la solicitud. Si configuras el servicio de recuperación de URL para que no siga redireccionamientos, App Engine agregará este encabezado a las consultas de manera automática. Consulta Cómo inhabilitar los redireccionamientos para obtener orientación sobre cómo inhabilitar los redireccionamientos.

Próximos pasos

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, en Solicitudes salientes.

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

Enviar comentarios sobre...

Entorno estándar de App Engine para Java