5

I would like to make a simple HTTP HEAD request, without keep-alive.

How can I do that in Android?

4

3 回答 3

8

使用 HttpClient

正如 njzk2 所建议HttpClient()的那样,它非常简单:

HttpResponse response = new HttpClient().execute(new HttpHead(myUrl));

但是存在无法关闭连接的问题。通常在 HttpClient 上,您将使用以下方法获取实体:

HttpEntity entity = response.getEntity();

然后你会从实体获取输入流

InputStream instream = entity.getContent();
...
instream.close();

并通过关闭输入流,连接将关闭。但是,在 HEAD 请求的情况下,实体似乎是null(可能是因为 HEAD 请求不会在响应中返回正文),因此无法获取和关闭输入流,并且连接也不会关闭。

在对他的回答的最后一次编辑中,njzk2 建议使用AndroidHttpClient,这是一个更新的实现(API 8),HttpClient它实际上有一个close()方法。我没用过,但我想它会很好用。但是,正如 Android 开发团队所建议的,HttpUrlConnection应该是首选的 Android 客户端。

使用 HttpUrlConnection

HEAD实际上,使用请求HttpUrlConnection并确保连接关闭似乎很容易:

    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();
        }
    }
于 2014-03-20T21:17:04.877 回答
1

微不足道:

HttpResponse response = new AndroidHttpClient().execute(new HttpHead(myUrl));

通常你会AndroidHttpClient为几个连接使用相同的,然后调用close它。

于 2014-03-20T18:11:43.027 回答
1

对于普通的 Java 和 Android

如果参数 if_modified_since 不为零,我正在使用一些标准 Java 代码来测试资源的存在并同时检查资源是否已更改。

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

有趣的是,代码需要一个 con.getInputStream() 并且我在这里没有得到一些错误。但是我需要一些帮助代码,以适应指向 JAR 的 URI。辅助代码是:

     private static long getLastModified(URLConnection con) 
                    throws IOException {
    if (con instanceof JarURLConnection) {
        return ((JarURLConnection) con).getJarEntry().getTime();
    } else {
        return con.getLastModified();
    }
}

如果 URI 是 schema file: ,则可以通过一些专门化进一步优化代码,然后可以直接执行 File.exists() 和 File.getLastModified()。

我们在这里不抛出 ServiceUnvailable 异常,我们基本上假设外部代码会捕获 IOException,然后假设 getHead() 的错误结果。

于 2016-08-14T15:52:43.840 回答