Issuing HTTP(S) Requests

This page describes how to issue HTTP(S) requests from your App Engine app using the URL Fetch Service.

If you use the Java 7 runtime, you must use the URL Fetch service to issue outbound HTTP(S) requests. If you use the Java 8 runtime, you aren't required to use the URL Fetch service for outbound requests, although the Java 8 runtime continues to support URL Fetch.

For details about how the URL Fetch service is implemented and which headers are sent in a URL Fetch request, see Outbound Requests.

URL Fetch and Java 7/Java 8 runtime compatibility

You can use URLFetch in either of the following ways shown in the table, which shows the differences by runtime:

URLFetch usage method Java 7 Java 8
UrlFetch API Calls Use classes in com.google.appengine.urlfetch.*.
Free quota available.
Use classes in com.google.appengine.urlfetch.*.
Free quota available.
Use native Java methods for opening URLs.
For example java.net.URL.openConnection.
The Java 7 runtime handles even native Java requests using URL Fetch. The Java 8 runtime handles native requests using native Java. To change this to force the use of URL Fetch to handle those calls, add the setting urlfetch to your appengine-web.xml file.

You can use native Java with no URL Fetch handling by specifying native, but this is available only to Java 8 billed apps, not to free Java 8 apps or Java 7 apps.

There is no free quota with native Java. If you use the native setting with free Java 8 apps you will get exceptions, such as java.net.UnknownHostException, java.net.SocketTimeoutException, or java.io.IOException.

For more information on setting , see the appengine-web.xml Reference(.

Issuing an HTTP request

If you are using URL Fetch, you issue an outbound HTTP request using java.net.URLConnection.

The following snippet demonstrates how to perform a basic HTTP GET request. The application creates a new URL object, then calls the object's openStream() method to retrieve the content at that URL:

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

For more advanced requests, use java.net.HttpURLConnection as follows:

  1. Create a new URL object.
  2. Create a new URLConnection object by calling your URL object's openConnection() method.
  3. Create a new HttpURLConnection object by casting your URLConnection object to the HttpURLConnection object type.
  4. Set the HttpURLConnection object's request method.
  5. Create an output stream for the request.
  6. Write the request payload to the stream.
  7. Close the stream.

The following snippet demonstrates how to use HttpURLConnection to perform a more advanced request, submitting data from a web form via a PUT request:

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

Java 8

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

Setting a request timeout

You can adjust the default deadline for requests using the appengine.api.urlfetch.defaultDeadline setting in the appengine-web.xml file.

Setting headers

To set an HTTP header on the outgoing request, call your HttpURLConnection object's setRequestProperty() method. The following snippet sets the X-MyApp-Version header to 2.7.3:

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

Disabling redirects

By default, HttpURLConnection follows HTTP redirects. The underlying URL Fetch service will follow up to five redirects. To disable this behavior, pass the value false to your HttpURLConnection object's setInstanceFollowRedirects() method:

connection.setInstanceFollowRedirects(false);

If your app uses the underlying urlfetch package directly instead of java.net, your app must specify doNotFollowRedirects.

Issuing an HTTPS request

To issue an HTTPS request, use the FetchOptions class in the urlfetch package and call validateCertificate().

Issuing an asynchronous request

HTTP(S) requests are synchronous by default. To issue an asynchronous request, your application must use URLFetchService's fetchAsync() method. This method returns a java.util.concurrent.Future<HTTPResponse>.

Issuing a request to another App Engine app

When issuing a request to another App Engine app, your App Engine app must assert its identity by adding the header X-Appengine-Inbound-Appid to the request. If you instruct the URL Fetch service to not follow redirects, App Engine will add this header to requests automatically. See Disabling redirects for guidance on disabling redirects.

What's next

Learn about the URL Fetch service, such as the headers that are sent in a URL Fetch request in Outbound Requests.

Send feedback about...

App Engine standard environment for Java