Повторное использование HttpURLConnection, чтобы поддерживать сеанс

У нас есть приложение для Android, которое требует от пользователя ввода ответа на капчу. Капча генерируется на нашем сервере. При ответе он отправляется на сервер для проверки.

Проблема в том, что, поскольку я должен закрыть HttpURLConnection после запроса Captcha, я обнаруживаю, что ответ выполняется в другом сеансе на сервере. Из-за этого проверка Captcha не выполняется, поскольку она зависит от сеанса.

Есть ли способ сохранить соединение или я должен идти по другому пути? Я знаю, что в аналогичном приложении для iPhone они остаются «подключенными» и, следовательно, имеют один и тот же идентификатор сеанса.

Редактировать:

    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();

person theblitz    schedule 23.05.2012    source источник


Ответы (2)


Обычно сеансы не сохраняются на основе самого http-соединения. Это не имело бы никакого смысла. Сеансы обычно поддерживаются с помощью файла cookie на стороне клиента и информации о сеансе на стороне сервера. Что вам нужно сделать, так это сохранить файлы cookie, которые вы получаете, а затем установить эти файлы cookie при следующем подключении к серверу.

Чтобы узнать больше о том, как работать с сеансами и файлами cookie с помощью класса HttpUrlConnection, прочитайте документацию: http://developer.android.com/reference/java/net/HttpURLConnection.html

Вот небольшой отрывок для начала:

Чтобы установить и поддерживать потенциально долговременный сеанс между клиентом и сервером, HttpURLConnection включает расширяемый диспетчер файлов cookie. Включите управление файлами cookie на уровне виртуальной машины с помощью CookieHandler и CookieManager:

CookieManager cookieManager = new CookieManager();  
CookieHandler.setDefault(cookieManager);

РЕДАКТИРОВАТЬ:

Для тех, кто работает с уровнями 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.java. Обратите внимание на имя переменной (из репозитория Android Open Source Project (AOSP)):

 37 /**
 38      * Sets the system-wide cookie handler.
 39      */
 40     public static void setDefault(CookieHandler cHandler) {
 41         systemWideCookieHandler = cHandler;
 42     }
person DallaRosa    schedule 23.05.2012
comment
После того, как я определил CookieManager, нужно ли добавить тот, который содержит идентификатор сеанса? - person theblitz; 23.05.2012
comment
Хорошо, у меня к вам важный вопрос: вы используете API 9+ (2.3+)? ЕСЛИ да, вы просто добавляете, что перед подключением все должно быть в порядке. Если вы используете 2.2 или меньше, вам следует использовать HttpClient из пакета org.apache. Если вы делаете для 2.2, я добавлю пример кода. - person DallaRosa; 23.05.2012
comment
На данный момент он установлен на 2.3, но не уверен, что мы собираемся оставить его таким. Может скинуть на 2.2, но не уверен. Кажется, что 99% устройств здесь 2.3+, так что все должно быть в порядке. - person theblitz; 23.05.2012
comment
Ok. Так что тебе должно быть хорошо. Попробуйте это и дайте мне знать, если это сработало. Я добавлю код для использования с библиотекой Apache ради следующего человека, который наткнется на это. - person DallaRosa; 23.05.2012
comment
Все еще не уверен, как это должно работать. Нужно ли мне каким-то образом подключаться к диспетчеру файлов cookie? Я отредактировал, чтобы включить свой код. - person theblitz; 23.05.2012
comment
CookieHandler.setDefault(cookieManager); Строка выше устанавливает созданный вами объект cookieManager в качестве обработчика cookie по умолчанию для всех подключений. - person DallaRosa; 23.05.2012
comment
давайте продолжим это обсуждение в чате - person DallaRosa; 23.05.2012

Чтобы поддерживать сеанс с помощью HttpURLConnection, вам нужно выполнить эту часть

CookieManager cookieManager = new CookieManager();  
CookieHandler.setDefault(cookieManager);

только один раз и не при каждом подключении. Хороший кандидат может быть на запуск приложения внутри Application.onCreate();

person Grigori A.    schedule 26.05.2014