3

我必须登录 https 网页并使用 Java 下载文件。我事先知道所有的网址:

baseURL = // a https URL;
urlMap = new HashMap<String, URL>();
urlMap.put("login", new URL(baseURL, "exec.asp?login=username&pass=XPTO"));
urlMap.put("logout", new URL(baseURL, "exec.asp?exec.asp?page=999"));
urlMap.put("file", new URL(baseURL, "exec.asp?file=111"));

如果我在 Firefox 等网络浏览器中尝试所有这些链接,它们就会起作用。

现在当我这样做时:

urlConnection = urlMap.get("login").openConnection();
urlConnection.connect();
BufferedReader in = new BufferedReader(
    new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
    System.out.println(inputLine);
in.close();

我只是再次返回登录页面 HTML,但无法继续下载文件。

谢谢!

4

5 回答 5

5

我同意 Alnitak 的观点,即问题可能在于存储和返回 cookie。

我使用的另一个不错的选择是来自 Jakarta Commons的HttpClient 。

顺便说一句,值得注意的是,如果这是您控制的服务器,您应该知道将用户名和密码作为查询字符串发送是不安全的(即使您使用的是 HTTPS)。HttpClient 支持使用 POST 发送参数,您应该考虑这一点。

于 2009-01-07T17:57:24.243 回答
4

如前所述,您必须在请求之间维护会话 cookie(请参阅CookieHandler)。

这是一个示例实现:

class MyCookieHandler extends CookieHandler {

    private Map<String, List<String>> cookies = new HashMap<String, List<String>>();

    @Override
    public Map<String, List<String>> get(URI uri,
            Map<String, List<String>> requestHeaders) throws IOException {
        String host = uri.getHost();
        Map<String, List<String>> ret = new HashMap<String, List<String>>();
        synchronized (cookies) {
            List<String> store = cookies.get(host);
            if (store != null) {
                store = Collections.unmodifiableList(store);
                ret.put("Cookie", store);
            }
        }

        return Collections.unmodifiableMap(ret);
    }

    @Override
    public void put(URI uri, Map<String, List<String>> responseHeaders)
            throws IOException {
        List<String> newCookies = responseHeaders.get("Set-Cookie");
        if (newCookies != null) {
            String host = uri.getHost();
            synchronized (cookies) {
                List<String> store = cookies.get(host);
                if (store == null) {
                    store = new ArrayList<String>();
                    cookies.put(host, store);
                }
                store.addAll(newCookies);
            }
        }
    }

}
于 2009-01-07T20:51:33.813 回答
3

尽管您可能有其他问题阻止登录请求让您登录,但除非您存储并返回登录页面生成的任何 cookie,否则您不太可能继续下载页面。

那是因为 HTTP 本身是无状态的,所以在您当前的代码中,远程服务器无法判断第二个下载请求来自刚刚登录的同一用户。

于 2009-01-07T17:48:08.707 回答
2

我想说看看 Java CURL http://sourceforge.net/projects/javacurl。我以前用它来登录 https 网站并下载东西,它具有欺骗浏览器 ID 等功能。这可能会解决您重定向回登录的问题。

虽然他们为它提供了一个 eclipse 插件,但我没有使用它,它工作正常。

或者,您可以使用 wget 并从 java 调用它。

于 2009-01-07T17:46:36.293 回答
1

也许您想尝试HttpUnit。尽管在编写时考虑了网站测试,但它可能对您的问题有用。

从他们的网站:

“...... 用 Ja​​va 编写的 HttpUnit 模拟浏览器行为的相关部分,包括表单提交、JavaScript、基本 http 身份验证、cookie 和自动页面重定向,并允许 Java 测试代码检查返回的页面作为文本、XML DOM、或表格、表格和链接的容器。”

于 2009-01-07T18:06:19.060 回答