как разместить объект java.net.URLConnection, чтобы гарантировать, что последующие вызовы одного и того же URL-адреса не будут совместно использовать данные сеанса?

У меня проблема с вызовом одного и того же URL-адреса https несколько раз подряд. Первые запросы выполняются успешно, но через неопределенное время возникает исключение с кодом ошибки 401 HTTP, предполагающее, что учетные данные пользователя недействительны.

Я обсудил эту проблему с лицом, ответственным за базу данных/сервер, и он сказал мне, что проблема, с которой я столкнулся, была нормальной, потому что через определенное фиксированное время сервер делает недействительными данные сеанса, вызывая последующие вызовы того же URL-адреса с тем же учетные данные пользователя, чтобы привести к коду ошибки 401 HTTP.

Он указал, что если я позволю различным объектам URLConnection обрабатывать все необходимые вызовы, то мне не придется беспокоиться о просроченных данных сеанса.

Его объяснение кажется логичным, но, как показывает приведенный ниже фрагмент кода, я уже использую совершенно новый объект URLConnection для каждого запроса к одному и тому же URL-адресу с теми же учетными данными пользователя. Итак, если то, что мне сказали, верно, то я предполагаю, что проблема в том, что все объекты URLConnection используют одно и то же базовое соединение и по этой причине совместно используют одни и те же данные сеанса.

Предполагая, что я на правильном пути, как мне изменить свой код, чтобы каждый раз, когда я делаю новый запрос на тот же URL-адрес с теми же учетными данными пользователя, я не сталкивался с проблемами, вызванными просроченными данными сеанса? Это всего лишь вопрос вызова disconnect() для базового объекта HttpsURLConnection?

public static void main(String[] args)
{
    String url = "https://...";//some https url
    int x = 0;
    while(true)
    {
        try
        {
            System.out.print("call#: " + (++x));

            //call download() with a valid username & password
            String result = download(url, "some-valid-username", "some-valid-password");
            System.out.println(result);
        }
        catch(Throwable e)
        {
            //after hundreds of successful calls,
            //a 401 HTTP error code exception
            e.printStackTrace();
            break;
        }
    }
}

public static String download(String url, String user, String pass) throws IOException
{
    //new URLConnection object
    java.net.URLConnection connection = new java.net.URL(url).openConnection();
    connection.setRequestProperty("Authorization",
            "Basic " +
                javax.xml.bind.DatatypeConverter.printBase64Binary(
                        (user + ":" + pass).getBytes("UTF-8")));

    //get response
    InputStream is = null;
    byte[] response = null;
    try
    {
        is = connection.getInputStream();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        byte[] bytes = new byte[16384];
        int x = 0;
        while((x = is.read(bytes, 0, bytes.length)) != -1){
            stream.write(bytes, 0, x);
        }
        stream.flush();
        response = stream.toByteArray();
    }
    finally
    {
        if (is != null)
        {
            is.close();
        }
    }
    //((javax.net.ssl.HttpsURLConnection)connection).disconnect();// ?

    return response != null ? new String(response, "UTF-8") : null;
}

person J Smith    schedule 24.07.2013    source источник
comment
в настоящее время я не знаю решения для вас, вероятно ... но, если вы работаете на платформе Windows, загрузите программу TCPView и проверьте, действительно ли ваш код создает разные (совершенно новые) TCP-соединения, когда эта загрузка () вызывается каждый раз .. Совет: введите некоторую задержку между каждым вызовом, используя thread.sleep(), чтобы упростить отладку. Сообщите мне о результатах...   -  person Dreamer    schedule 24.07.2013


Ответы (1)


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

Пожалуйста, прочтите это

http://en.wikipedia.org/wiki/Session_%28computer_science%29

person Prabhakaran Ramaswamy    schedule 24.07.2013