как поддерживать переменные файлы cookie и сеансы с помощью jsoup?

public boolean isGood(String path)
{
    if (p != path)
    {
        good = false;
    }

    if (good)
    {
        try 
        {
            Connection connection = Jsoup.connect(path);
            Map<String, String> cookys = Jsoup.connect(path).response().cookies();

            if (cookys != cookies)
                cookies = cookys;

            for (Entry<String, String> cookie : cookies.entrySet()) 
            {
                connection.cookie(cookie.getKey(), cookie.getValue());
            }

            Doc = connection.get();
            good = true;
        }
        catch (Exception e) 
        {
            rstring = e.getMessage().toString();
            good = false;
        }
    }
    else
    {
        try
        {
            Response response = Jsoup.connect(path).execute();
            cookies = response.cookies();
            Doc = response.parse();
            good = true;
        }
        catch (Exception e) 
        {
            rstring = e.getMessage().toString();
            good = false;
        } 
    }       
    return good;
}

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

Я пишу приложение для своего форума простых машин, и оно меняет свою конфигурацию cookie, когда вы нажимаете на нее для некоторого пользовательского поведения.

Но если приложение подойдет для моего сайта, я собирался опубликовать версию, которую другие могли бы использовать на других форумах.

Я знаю, что иду в правильном направлении, но логика как бы надирает мне задницу.

Мы будем очень признательны за любые советы.


person texasman1979    schedule 11.10.2011    source источник
comment
В дополнение к комментариям BalusC, маловероятно, что p != path это то, что вы действительно имеете в виду, хотя это возможно.   -  person Dave Newton    schedule 11.10.2011


Ответы (2)


Этот код очень запутанный. Поток нелогичен, а обработка исключений плохая. Сравнения ссылок на объекты, такие как if (p != path) и if (cookys != cookies), не имеют никакого смысла. Чтобы сравнить содержимое объекта, вам нужно использовать метод equals().

К слову, я понимаю, что вы хотите сохранить файлы cookie в куче последующих запросов Jsoup на том же домене. В этом случае вам нужно в основном придерживаться следующего алгоритма действий:

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

// First request.
Connection connection1 = Jsoup.connect(url1);
for (Entry<String, String> cookie : cookies.entrySet()) {
    connection1.cookie(cookie.getKey(), cookie.getValue());
}
Response response1 = connection1.execute();
cookies.putAll(response1.cookies());
Document document1 = response1.parse();
// ...

// Second request.
Connection connection2 = Jsoup.connect(url2);
for (Entry<String, String> cookie : cookies.entrySet()) {
    connection2.cookie(cookie.getKey(), cookie.getValue());
}
Response response2 = connection2.execute();
cookies.putAll(response2.cookies());
Document document2 = response2.parse();
// ...

// Third request.
Connection connection3 = Jsoup.connect(url3);
for (Entry<String, String> cookie : cookies.entrySet()) {
    connection3.cookie(cookie.getKey(), cookie.getValue());
}
Response response3 = connection3.execute();
cookies.putAll(response3.cookies());
Document document3 = response3.parse();
// ...

// Etc.

Это можно преобразовать в следующий метод:

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

public Document get(url) throws IOException {
    Connection connection = Jsoup.connect(url);
    for (Entry<String, String> cookie : cookies.entrySet()) {
        connection.cookie(cookie.getKey(), cookie.getValue());
    }
    Response response = connection.execute();
    cookies.putAll(response.cookies());
    return response.parse();
}

который можно использовать как

YourJsoupWrapper jsoupWrapper = new YourJsoupWrapper();

Document document1 = jsoupWrapper.get(url1);
// ...

Document document2 = jsoupWrapper.get(url2);
// ...

Document document3 = jsoupWrapper.get(url3);
// ...

Обратите внимание, что в грядущей версии Jsoup 1.6.2 будет новый метод Connection#cookies(Map), который должен делать этот цикл for каждый раз излишним.

person BalusC    schedule 11.10.2011
comment
я благодарю вас очень много. я искал и искал пример правильного способа сделать это. этот способ определенно лучше, чем тот, который я пытался. ржу не могу - person texasman1979; 11.10.2011
comment
Кто-то из будущего! по какой-то причине я нашел JSoup очень удобным. Мои два цента в том, что в текущей библиотеке JSoup есть метод с именем cookies (Map‹String,String› cookies), который добавляет пары ключ/значение. Таким образом, указанный выше foreach можно заменить на: connection.cookies (cookies) - person Jose Cifuentes; 21.03.2014
comment
вы можете сделать connection.cookies(cookies) вместо цикла for - person caub; 20.03.2015
comment
@crl: Действительно, см. также последний абзац приведенного выше ответа и комментарии разработчика Jsoup к этому ответу. - person BalusC; 20.03.2015

+1 за BalusC

Я кое-что изменил в вашем коде, и он работает для меня, так что вы получаете cookie с сайта и только потом получаете документ

public Document get(String url) throws IOException {
    Connection connection = Jsoup.connect(url).userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
    Connection.Response response = connection.execute();
    connection.cookies(response.cookies());
    return connection.get();
}
person Bender    schedule 17.11.2013