Повторное использование HttpURLConnection для сохранения сеанса
у нас есть приложение для Android, которое требует от пользователя ввести ответ на капчу. Капча генерируется на нашем сервере. Когда ответы, он отправляется на сервер для проверки.
проблема в том, что, поскольку я должен закрыть HttpURLConnection после запроса на Captcha, я затем нахожу, что ответ выполняется на другом сеансе на sever. Из-за этого проверка Captcha не выполняется, поскольку она зависит от сеанса.
есть ли способ сохранить соединение живое или я должен следовать другим путем? Я знаю, что в эквивалентном приложении iPhone они остаются "подключенными" и, следовательно, имеют тот же sessionid.
изменить:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
URL urlObj = new URL(urlPath);
conn = (HttpURLConnection) urlObj.openConnection();
if (urlPath.toLowerCase().startsWith("https:")) {
initializeHttpsConnection((HttpsURLConnection) conn);
}
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Language", "en-US");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(bodyData.length));
if (_sessionIdCookie != null) {
conn.setRequestProperty("Cookie", _sessionIdCookie);
}
// Connect
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
2 ответов
обычно сеансы не сохраняются на основе самого http-соединения. В этом нет никакого смысла. Сеансы обычно поддерживаются через cookie на стороне клиента и информацию о сеансе на стороне сервера. Что вам нужно сделать, это сохранить файлы cookie, которые вы получаете, а затем установить эти файлы cookie при следующем подключении к серверу.
чтобы узнать больше о том, как работать с сеансами и cookies с классом HttpUrlConnection, прочитайте документацию: http://developer.android.com/reference/java/net/HttpURLConnection.html
вот небольшой отрывок, чтобы вы начали:
установить и поддержать потенциально длинн-прожитую сессию между клиент и сервер, HttpURLConnection включает расширяемый файл cookie менеджер. Включить управление файлами cookie на уровне VM с помощью CookieHandler и Cookiemanager, как:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
EDIT:
для тех, кто работает с уровнями API 8 или ниже, вам нужно будет использовать библиотеку Apache!
вот некоторый код ссылки:
// Create a local instance of cookie store
CookieStore cookieStore = new BasicCookieStore();
// Create local HTTP context
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet httpget = new HttpGet("http://www.google.com/");
System.out.println("executing request " + httpget.getURI());
// Pass local context as a parameter
HttpResponse response = httpclient.execute(httpget, localContext);
приведенный выше код был взят из примеров библиотеки Apache. Его можно найти здесь: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomContext.java
редактирование 2: вношу ясность:
для библиотеки Apache вам нужно как-то" подключить" объект управления cookie с объектом подключения, и вы делаете это через объект HttpContext.
В случае HttpUrlConnection это не обязательно. при использовании статического метода CookieHandler setDefault, вы устанавливаете общесистемный cookieHandler. Ниже приведен отрывок из CookieHandler.Ява. Обратите внимание на имя переменной (из репозитория проекта с открытым исходным кодом Android (AOSP)):
37 /**
38 * Sets the system-wide cookie handler.
39 */
40 public static void setDefault(CookieHandler cHandler) {
41 systemWideCookieHandler = cHandler;
42 }
для поддержания сеанса с помощью HttpURLConnection
вам нужно выполнить эту часть
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
только один раз и не на каждое соединение. Хороший кандидат может быть на запуске приложения внутри Application.onCreate();