java - 如何处置 java.net.URLConnection 对象以确保对同一 URL 的后续调用不会共享 session 数据?

标签 java session https http-status-codes urlconnection

我连续多次调用同一个 https URL 时遇到问题。第一次请求成功,但在不确定的时间后,会抛出 401 HTTP 错误代码异常,表明用户凭据无效。

我与数据库/服务器负责人讨论了这个问题,他告诉我,我遇到的问题是正常的,因为经过一段固定的时间后,服务器会使 session 数据失效,导致后续调用同一 URL使用相同的用户凭据会导致 401 HTTP 错误代码。

他表示,如果我让不同的 URLConnection 对象处理所有需要进行的调用,那么我就不必担心过期的 session 数据。

他的解释似乎有道理,但正如下面的代码片段所示,我已经为具有相同用户凭据的同一 url 的每个请求使用了一个全新的 URLConnection 对象。因此,如果我被告知的是正确的,那么我猜问题在于 URLConnection 对象都使用相同的底层连接,因此共享相同的 session 数据。

假设我走在正确的轨道上,我应该如何修改我的代码,以便每次使用相同的用户凭据向同一 URL 发出新请求时,我不会遇到由过期 session 数据引起的问题?这只是在底层 HttpsURLConnection 对象上调用 disconnect() 的问题吗?

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;
}

最佳答案

服务器将根据您的登录凭据创建 session ID,并由服务器维护。您的后续调用将根据 session ID 进行验证,而不是根据您的凭据进行验证。 您需要首先获取 session ID 并在您的应用程序中维护。将其传递给服务器以供后续调用。如果没有向服务器发送请求,则 session 将在一定的预定时间段后过期。

请阅读

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

关于java - 如何处置 java.net.URLConnection 对象以确保对同一 URL 的后续调用不会共享 session 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17841456/

相关文章:

java - 尽管已经提交了解决方案,但我无法解决 ArrayIndexOutOfBoundsException

java - 由 : org. springframework.beans.factory.NoSuchBeanDefinitionException 引起:运行测试时

java - 在电脑上运行 vaadin 应用程序

php访问HTTPS和HTTP之间的 session 数据

html - 混合 http 和 https

security - 友好 URL 在 HTTPS 下是否安全?

java - 为什么 junit 中的 assertEquals 和 assertSame 为同一类的两个实例返回相同的结果?

php - CMS 或框架中的实时分析用户数据

php - 在 PHP 中销毁 session 时出错

ssl - 将自签名 ssl 证书绑定(bind)到端口失败