Повторное использование 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();