13

我们有一个 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();
4

2 回答 2

13

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

要了解有关如何使用 HttpUrlConnection 类处理会话和 cookie 的更多信息,请阅读文档:http: //developer.android.com/reference/java/net/HttpURLConnection.html

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

为了在客户端和服务器之间建立和维护一个潜在的长期会话,HttpURLConnection 包括一个可扩展的 cookie 管理器。使用 CookieHandler 和 CookieManager 启用 VM 范围的 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     }
于 2012-05-23T07:18:48.340 回答
12

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

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

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

于 2014-05-26T08:12:03.210 回答