2012-05-23 128 views
12

我们有一个Android应用程序,要求用户输入对验证码的答案。 验证码在我们的服务器上生成。 当答复时,它被发送到服务器进行验证。重复使用HttpURLConnection以保持会话活跃

问题是,因为我必须在验证码请求后关闭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(); 

回答

13

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

要了解更多有关如何使用与HttpURLConnection的课堂,并且Cookie的工作,阅读文档:http://developer.android.com/reference/java/net/HttpURLConnection.html

这一点摘录,让你开始:

为了建立和保持一个潜在的 客户端和服务器之间的长时间会话,HttpURLConnection包括一个可扩展的cookie 管理器。使用的CookieHandler和 CookieManager启用虚拟机级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: 这就很清楚:

对于你需要以某种方式与连接对象“连接”的cookie管理对象的Apache库,但通过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  } 
+0

一旦我定义了“CookieManager”,然后我添加一个持有sessionid? – theblitz

+0

好的,我对你有一个重要的问题:你使用API​​ 9+(2.3+)吗?如果是的话,你只需在连接之前添加,你应该没问题。如果您使用的是2.2或更低版本,则应该使用org.apache包中的HttpClient。如果你在做2.2,我会添加一些示例代码。 – DallaRosa

+0

目前它被设置为2.3,但不确定我们将如何离开它。可能会将其降到2.2以下,但不确定。似乎这里有99%的设备是2.3+,所以应该没问题。 – theblitz

11

维护会话使用HttpURLConnection你需要在每个连接上

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

只有一次,不能执行这一部分。好的候选人可以在里面的应用程序启动Application.onCreate();