I would like to make a simple HTTP HEAD request, without keep-alive.
How can I do that in Android?
using HttpClient:
As njzk2 suggested, with HttpClient()
it's very straightforward:
HttpResponse response = new HttpClient().execute(new HttpHead(myUrl));
However there is a problem with not being able to close the connection. Usually on the HttpClient, you would get the entity using:
HttpEntity entity = response.getEntity();
and then you would get the input stream from the entity
InputStream instream = entity.getContent();
...
instream.close();
and by closing the input stream, the connection would close.
However, in the case of a HEAD request, the entity appears to be null
(possibly because HEAD requests don't return the body in the response), so the input stream cannot be fetched and closed and the connection doesn't close either.
In the last edit to his answer, njzk2 is suggesting to use AndroidHttpClient
, which is a more recent implementation (API 8) of HttpClient
and it actually has a close()
method. I haven't used it but I guess it will work fine. However, as the Android development team suggests, the HttpUrlConnection
should be the preferred Android client to use.
using HttpUrlConnection:
Actually it seems quite easy to make HEAD
requests using HttpUrlConnection
and make sure that the connection closes:
HttpURLConnection urlConnection = null;
System.setProperty("http.keepAlive", "false");
try {
URL url = new URL(stringUrl);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("HEAD");
urlConnection.getInputStream().close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
Trivially :
HttpResponse response = new AndroidHttpClient().execute(new HttpHead(myUrl));
Typically you'll use the same AndroidHttpClient
for several connections, then call close
on it.
For ordinary Java and Android
I am using some standard Java code to test the existence of a resource and in the same time to check whether a resource has been changed, provided the parameter if_modified_since is non-zero.
URL url = new URL(adr);
try {
URLConnection con = url.openConnection();
con.setIfModifiedSince(if_modified_since);
if (con instanceof HttpURLConnection) {
/* Workaround for https://code.google.com/p/android/issues/detail?id=61013 */
con.addRequestProperty("Accept-Encoding", "identity");
((HttpURLConnection) con).setRequestMethod("HEAD");
int response = ((HttpURLConnection) con).getResponseCode();
if (response == HttpURLConnection.HTTP_UNAVAILABLE)
return false;
if (response == HttpURLConnection.HTTP_NOT_MODIFIED)
return false;
}
if (if_modified_since != 0) {
long modified = OpenOpts.getLastModified(con);
if (modified != 0 && if_modified_since >= modified)
return false;
}
InputStream in = con.getInputStream();
in.close();
return true;
} catch (FileNotFoundException x) {
return false;
} catch (UnknownHostException x) {
return false;
} catch (SocketException x) {
return false;
}
Interestingly the code needs a con.getInputStream() and I don't get some errors here. But I needed some helper code, to also cater for URIs that point to JARs. The helper code is:
private static long getLastModified(URLConnection con)
throws IOException {
if (con instanceof JarURLConnection) {
return ((JarURLConnection) con).getJarEntry().getTime();
} else {
return con.getLastModified();
}
}
The code can be further optimized by some specialization if the URI is schema file: , one can then directly do File.exists() and File.getLastModified().
We do not throw a ServiceUnvailable exception here, we basically assume that the outer code would catch an IOException and then assume a false result of the getHead().