Como emitir solicitações HTTP(S)

Esta página descreve como emitir solicitações HTTP(S) do seu aplicativo App Engine.

Tempo de execução do Java 8 x comportamento do Java 7

Por padrão, os aplicativos executados no ambiente de execução do Java 8 usam classes Java padrão, como java.net.HttpURLConnection, em solicitações HTTP(S). Você envia solicitações exatamente como faria para qualquer outro aplicativo Java.

Quando o app é executado em Java 8 usando o comportamento padrão, você precisa habilitar o aplicativo para faturamento. Caso contrário, receberá as seguintes exceções:

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

O requisito de habilitar o aplicativo para faturamento existe, mas o app não gerará mais nenhum custo além do mesmo aplicativo em execução no Java 7.

Os aplicativos executados no ambiente de execução do Java 7 obsoleto também fazem chamadas usando classes Java padrão, como java.net.HttpURLConnection. No entanto, no tempo de execução do Java 7, essas chamadas são efetivamente processadas pelo serviço de busca de URL. Em vez das chamadas Java padrão, os aplicativos Java 7 têm a opção de usar a API URL Fetch do App Engine para usar o serviço de busca de URL diretamente.

Usar classes de rede do ambiente de execução padrão do Java 8

Se você usar as classes de rede padrão do Java no ambiente de execução do Java 8, seu aplicativo terá acesso aos seguintes recursos:

Como usar URLFetch em um app Java 8

Se você precisar usar o URL Fetch em um aplicativo Java 8, adicione a seguinte linha ao arquivo appengine-web.xml:

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

Por exemplo:

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

Esta configuração não exige que o app esteja com o faturamento ativado.

Como emitir solicitações HTTP

Uma solicitação HTTP de saída será emitida usando java.net.URLConnection.

O snippet a seguir demonstra como executar uma solicitação básica HTTP GET. O aplicativo cria um novo objeto URL e chama o método openStream() do objeto para recuperar o conteúdo nesse 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 solicitações mais avançadas, use java.net.HttpURLConnection da seguinte maneira:

  1. Crie um novo objeto URL.
  2. Crie um novo objeto URLConnection chamando o método openConnection() do objeto URL.
  3. Crie um novo objeto HttpURLConnection transmitindo o URLConnection para o tipo de objeto HttpURLConnection.
  4. Defina o método de solicitação do objeto HttpURLConnection.
  5. Crie um stream de saída para a solicitação.
  6. Grave o payload da solicitação no stream.
  7. Feche o stream.

O snippet a seguir demonstra como usar HttpURLConnection para executar uma solicitação mais avançada, enviando dados de um formulário da Web por meio de uma solicitação 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());
}

Como definir um tempo limite da solicitação

Se você estiver usando a busca de URL, poderá ajustar o prazo padrão para solicitações usando a configuração appengine.api.urlfetch.defaultDeadline no arquivo appengine-web.xml.

Como definir cabeçalhos

Se estiver usando a busca de URL, você poderá definir um cabeçalho HTTP na solicitação de saída chamando o método setRequestProperty() do objeto HttpURLConnection. O seguinte snippet define o cabeçalho X-MyApp-Version como 2.7.3:

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

Como desativar redirecionamentos

Por padrão, HttpURLConnection segue redirecionamentos HTTP. Se você estiver usando a busca de URL, o serviço de busca de URL subjacente seguirá até cinco redirecionamentos. Para desativar esse comportamento, passe o valor false para o método setInstanceFollowRedirects() do objeto HttpURLConnection:

conn.setInstanceFollowRedirects(false);

Se você usar o pacote urlfetch subjacente diretamente em vez de java.net, o app precisará especificar doNotFollowRedirects.

Como emitir solicitações HTTPS

Se você estiver usando a busca de URL, emita uma solicitação HTTPS usando a classe FetchOptions no pacote urlfetch e chame validateCertificate().

Como emitir uma solicitação assíncrona

As solicitações HTTP(S) são síncronas por padrão. Para emitir uma solicitação assíncrona, seu aplicativo precisa usar o método fetchAsync() do URLFetchService, que retorna um java.util.concurrent.Future<HTTPResponse>.

Como emitir solicitações para outro aplicativo do App Engine

Durante a emissão de uma solicitação para outro app do App Engine, o app do App Engine precisa declarar a identidade sele adicionando o cabeçalho X-Appengine-Inbound-Appid à solicitação. Se você instruir o serviço de busca de URL para não seguir redirecionamentos, o App Engine adicionará esse cabeçalho a solicitações automaticamente. Consulte Como desativar redirecionamentos para orientação sobre como desativar redirecionamentos.

Próximas etapas

Para saber mais sobre o serviço de busca de URL, como os cabeçalhos que são enviados em uma solicitação de busca de URL, consulte Solicitações de saída.

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Ambiente padrão do App Engine para Java 8