Android 重用 HttpURLConnection 以保持会话活动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10714943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:43:21  来源:igfitidea点击:

Reusing HttpURLConnection so as to keep session alive

androidhttpurlconnectionsessionid

提问by theblitz

We have an Android application that requires the user to enter an answer to a Captcha. The Captcha is generated on our server. When the replies, it is sent to the server for verifying.

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

Problem is that since I have to close the HttpURLConnection after the request for the Captcha I then find that the reply is running on a different session on the sever. Because of this the Captcha check fails since it is session dependant.

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

Is there a way to keep the connection alive or should I be following a different path? I know that in the equivalent iPhone application they remain "connected" and thus have the same sessionid.

有没有办法让连接保持活动状态,或者我应该遵循不同的路径?我知道在等效的 iPhone 应用程序中,它们保持“连接”状态,因此具有相同的 sessionid。

Edit:

编辑:

    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();

回答by DallaRosa

Normally, sessions are not kept based on the http connection itself. That wouldn't make any sense. Sessions are normally kept alive through a cookie on the client side and session information on the server side. What you gotta do is save the cookie(s) you're receiving and then setting that(those) cookie(s) next time you connect to the server.

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

To learn more about how to work with sessions and cookies with the HttpUrlConnection class, read the documentation: http://developer.android.com/reference/java/net/HttpURLConnection.html

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

Here a little excerpt to get you started:

这里有一个小摘录,让你开始:

To establish and maintain a potentially long-lived session between client and server, HttpURLConnection includes an extensible cookie manager. Enable VM-wide cookie management using CookieHandler and CookieManager:

为了在客户端和服务器之间建立和维护一个潜在的长期会话,HttpURLConnection 包括一个可扩展的 cookie 管理器。使用 CookieHandler 和 CookieManager 启用 VM 范围的 cookie 管理:

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

EDIT:

编辑:

For those working with API levels 8 or lower, you'll need to use Apache's library!

对于那些使用 API 级别 8 或更低级别的人,您需要使用 Apache 的库!

Here's some reference code:

这是一些参考代码:

 // 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);

The code above was taken from the Apache's library examples. It can be found here: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomContext.java

上面的代码取自 Apache 的库示例。可以在这里找到:http: //svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientCustomContext.java

EDIT 2: Making it clear:

编辑2: 明确说明:

For the Apache library you need to somehow "connect" the cookie management object with the connection object and you do that through the HttpContext object.

对于 Apache 库,您需要以某种方式将 cookie 管理对象与连接对象“连接”,并且您可以通过 HttpContext 对象来实现。

In HttpUrlConnection's case that's not necessary. when you use CookieHandler's static method setDefault, you're setting the system-wide cookieHandler. Below is an excerpt from CookieHandler.java. Note the variable name (from the Android Open Source Project's (AOSP) repository):

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

回答by Grigori A.

To maintain session using HttpURLConnectionyou need to execute this part

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

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

only once and not on every connection. Good candidate can be on application launch inside Application.onCreate();

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