【问题标题】:Reusing HttpURLConnection so as to keep session alive重用 HttpURLConnection 以保持会话活动
【发布时间】:2012-05-29 16:56:57
【问题描述】:

我们有一个 Android 应用程序,要求用户输入验证码的答案。 验证码是在我们的服务器上生成的。 当回复时,它被发送到服务器进行验证。

问题是,由于我必须在请求验证码后关闭 HttpURLConnection,然后我发现回复正在服务器上的不同会话上运行。 因此,验证码检查失败,因为它依赖于会话。

有没有办法让连接保持活跃,或者我应该走一条不同的路? 我知道在等效的 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();

【问题讨论】:

    标签: android httpurlconnection sessionid


    【解决方案1】:

    通常,会话不会基于 http 连接本身而保留。那没有任何意义。会话通常通过客户端的 cookie 和服务器端的会话信息保持活动状态。 您需要做的是保存您收到的 cookie,然后在下次连接到服务器时设置该(那些)cookie。

    要详细了解如何使用 HttpUrlConnection 类处理会话和 cookie,请阅读文档:http://developer.android.com/reference/java/net/HttpURLConnection.html

    这里有一些摘录让你开始:

    建立和维护一个潜在的长期会话 客户端和服务器,HttpURLConnection 包含一个可扩展的 cookie 经理。使用 CookieHandler 和 Cookie 管理器:

    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 开源项目 (AOSP) 存储库):

     37 /**
     38      * Sets the system-wide cookie handler.
     39      */
     40     public static void setDefault(CookieHandler cHandler) {
     41         systemWideCookieHandler = cHandler;
     42     }
    

    【讨论】:

    • 一旦我定义了“CookieManager”,我会添加一个保存 sessionid 的吗?
    • 好的,我有一个重要的问题要问您:您使用的是 API 9+ (2.3+) 吗?如果是,您只需在连接之前添加它就可以了。如果您使用的是 2.2 或更低版本,您应该使用 org.apache 包中的 HttpClient。如果您正在使用 2.2,我将添加一些示例代码。
    • 目前它设置为 2.3,但不确定我们是否会这样。可能会降到 2.2 之前,但不确定。似乎这里 99% 的设备都是 2.3+,所以应该没问题。
    • 好的。所以你应该很好。试试看,让我知道它是否有效。我将添加与 Apache 库一起使用的代码,以方便下一个偶然发现此问题的人
    • 仍然不确定它应该如何工作。我是否需要以某种方式连接到 cookie 管理器来连接?我已编辑以包含我的代码。
    【解决方案2】:

    要使用HttpURLConnection 维护会话,您需要执行此部分

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

    只有一次,而不是每次连接。好的候选人可以在Application.onCreate();内的应用程序启动

    【讨论】:

      猜你喜欢
      • 2012-07-19
      • 1970-01-01
      • 2010-12-06
      • 2013-07-17
      • 1970-01-01
      • 2010-11-28
      • 2014-09-24
      • 1970-01-01
      相关资源
      最近更新 更多