重用 HttpURLConnection 以保持会话活动
Posted
技术标签:
【中文标题】重用 HttpURLConnection 以保持会话活动【英文标题】:Reusing HttpURLConnection so as to keep session alive 【发布时间】: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();
【问题讨论】:
【参考方案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();
内的应用程序启动
【讨论】:
以上是关于重用 HttpURLConnection 以保持会话活动的主要内容,如果未能解决你的问题,请参考以下文章
Java之HttpURLConnection的变态事: Keep-Alive
保持 HttpUrlConnection 调用之间的会话(本机/Webview)