Как мне войти в систему и загрузить файл с веб-страницы https с Java?
Вопрос
Я должен войти на веб-страницу https и загрузить файл, используя Java.Я заранее знаю все URL-адреса:
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 страницы входа в систему, и я не могу перейти к загрузке файла.
Спасибо!
Решение
Я согласен с Alnitak в том, что проблема, скорее всего, заключается в хранении и возврате файлов cookie.
Еще один хороший вариант, который я использовал, это С помощью HttpClient из Jakarta Commons.
В качестве отступления стоит отметить, что если это сервер, которым вы управляете, вы должны знать, что отправка имени пользователя и пароля в виде строк запроса небезопасна (даже если вы используете HTTPS).HttpClient поддерживает отправку параметров с помощью POST, что вам следует учитывать.
Другие советы
Как уже было отмечено, вы должны поддерживать сеансовый файл cookie между запросами (см. Кухонный манипулятор).
Вот пример реализации:
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);
}
}
}
}
Несмотря на то, что у вас может возникнуть какая-то другая проблема, которая мешает вам войти в систему с помощью запроса на вход, маловероятно, что вы сможете перейти на страницу загрузки, если вы не сохраните и не вернете все файлы cookie, которые генерирует страница входа.
Это потому, что сам HTTP не имеет состояния, поэтому в вашем текущем коде удаленный сервер не может сообщить, что второй запрос на загрузку исходит от того же пользователя, который только что вошел в систему.
Я бы сказал, взгляните на Java CURL http://sourceforge.net/projects/javacurl.Я использовал его раньше для входа на веб-сайт https и загрузки материалов, у него есть такие функции, как подделка идентификатора браузера и т.д.Что могло бы решить вашу проблему с перенаправлением обратно на вход в систему.
Хотя они предоставляют для этого плагин eclipse, я использовал его без него, и он работает нормально.
В качестве альтернативы вы могли бы использовать wget и вызвать его из java.
Возможно, вы хотите попробовать HttpUnit.Хотя он написан с учетом тестирования веб-сайтов, он может быть полезен для решения вашей проблемы.
С их веб-сайта:
"...Написанный на Java, HttpUnit эмулирует соответствующие части поведения браузера, включая отправку форм, JavaScript, базовую http-аутентификацию, файлы cookie и автоматическое перенаправление страниц, и позволяет тестовому коду Java проверять возвращаемые страницы либо в виде текста, XML DOM, либо контейнеров с формами, таблицами и ссылками ".