保持 HttpUrlConnection 调用之间的会话(本机/Webview)

Posted

技术标签:

【中文标题】保持 HttpUrlConnection 调用之间的会话(本机/Webview)【英文标题】:Maintain session between HttpUrlConnection Calls (Native/Webview) 【发布时间】:2016-02-07 06:30:35 【问题描述】:

让我从我渴望开始:

我想制作一个part native and part webviews 的应用程序。

问题 - 在本机部件和 web 视图部件之间保持会话。

我的处理方法

我打算实现一个本机登录,其中我向用户展示了两个 EditTextbox 和一个按钮,用户输入凭据并将它们作为 JSON 发布到服务器。

服务器响应成功或错误。根据 Success 标志,我读取此连接的标头值并提取 SessionCookie:

switch (responseCode) 
                case 200:

                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    String inputLine;
                    response = new StringBuffer();
                    while ((inputLine = in.readLine()) != null) 
                        response.append(inputLine);
                    
                    in.close();

                   //IF SUCCESS

                    Map<String, List<String>> map = conn.getHeaderFields();

                    for (Map.Entry<String, List<String>> entry : map.entrySet()) 
                        System.out.println("Key : " + entry.getKey() + " ,Value : " + entry.getValue());
                    

                    SSID = map.get("Set-Cookie").toString();
                    SSID = SSID.substring(1,SSID.length()-1);
                    return response.toString();
            

如下所示:

Set-Cookie ,Value : [phpSESSID=e407ef64abb71b1ea2b8e4b30db76cf0; path=/, ci_session=a%3A0%3A%7B%7D; expires=Thu, 06-Nov-2014 16:54:57 GMT; Max-Age=-31500000; path=/, ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D5f4013e4a2edd2eb891ec8a2b8e8716e; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/]

警告:在上面expires=Thu, 06-Nov-2014 16:54:57 GMT

现在我想去一个 webview 并将这个 cookie 添加到标题中,我正在这样做:

Map<String, String> abc = new HashMap<String, String>();
            abc.put("Cookie", UniversalHttpUrlConnection.SSID);
            webView.loadUrl("https://someUrl/show_all", abc);

但上述不起作用

我尝试了一种不同的方法,只是从上面的 webview URL 中读取html

 public static String doHttpUrlConnectionAction(String desiredUrl, String headerValue)
            throws Exception 
        URL url = null;
        BufferedReader reader = null;
        StringBuilder stringBuilder;

        try 

            url = new URL(desiredUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("Cookie", headerValue);

            connection.setRequestMethod("GET");

            connection.setDoOutput(true);


            connection.setReadTimeout(15 * 1000);
            connection.connect();


            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            stringBuilder = new StringBuilder();

            String line = null;
            while ((line = reader.readLine()) != null) 
                stringBuilder.append(line + "\n");
            
            return stringBuilder.toString();
         catch (Exception e) 
            e.printStackTrace();
            throw e;
         finally 

            if (reader != null) 
                try 
                    reader.close();
                 catch (IOException ioe) 
                    ioe.printStackTrace();
                
            
        

    

我得到的 HTML 是登录页面的 HTML,它本质上是一个重定向 - 因为服务器无法识别会话并重定向我。我在这里想念什么?如何继续会话?

编辑 - 进一步调试:

使用已弃用的:

HttpClient httpClient = new DefaultHttpClient(); //

我得到了这些标题:

Key : Date ,Value : Sat, 07 Nov 2015 08:22:28 GMT
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Server ,Value : Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : PHPSESSID=f27454f855fc5d5b2efa478537725992; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Expires ,Value : Thu, 19 Nov 1981 08:52:00 GMT
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Cache-Control ,Value : no-store, no-cache, must-revalidate, post-check=0, pre-check=0
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Pragma ,Value : no-cache
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A0%3A%7B%7D; expires=Fri, 07-Nov-2014 18:22:28 GMT; Max-Age=-31500000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D58938a4e97b08c01faa7fec0025bdc49; expires=Mon, 06-Nov-2017 08:22:28 GMT; Max-Age=63072000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3B%7D30e2cc6561b3fb9659c7809d0c82946d; expires=Mon, 06-Nov-2017 08:22:28 GMT; Max-Age=63072000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3B%7D30e2cc6561b3fb9659c7809d0c82946d; expires=Mon, 06-Nov-2017 08:22:28 GMT; Max-Age=63072000; path=/
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Vary ,Value : Accept-Encoding
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Content-Length ,Value : 95
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Connection ,Value : close
11-07 13:52:26.567 5264-5291/projects.test.com.webviewtest I/System.out: Key : Content-Type ,Value : text/html

一开始还有一个警告

Invalid cookie header: "Set-Cookie: ci_session=a%3A0%3A%7B%7D; expires=Fri, 07-Nov-2014 18:22:28 GMT; Max-Age=-31500000; path=/". Negative max-age attribute: -31500000

观察 Set-Cookie 来了 4 次,第一次导致异常。

现在使用 HttpUrlConnection:

HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();

以下是我得到的标题:

 Key : null ,Value : [HTTP/1.1 200 OK]
11-07 13:52:27.646 5264-5291/projects.test.com.webviewtest I/System.out: Key : Cache-Control ,Value : [no-store, no-cache, must-revalidate, post-check=0, pre-check=0]
11-07 13:52:27.646 5264-5291/projects.test.com.webviewtest I/System.out: Key : Connection ,Value : [close]
11-07 13:52:27.646 5264-5291/projects.test.com.webviewtest I/System.out: Key : Content-Type ,Value : [text/html]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Date ,Value : [Sat, 07 Nov 2015 08:22:29 GMT]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Expires ,Value : [Thu, 19 Nov 1981 08:52:00 GMT]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Pragma ,Value : [no-cache]
11-07 13:52:27.649 5264-5291/projects.test.com.webviewtest I/System.out: Key : Server ,Value : [Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4]
11-07 13:52:27.650 5264-5291/projects.test.com.webviewtest I/System.out: Key : Set-Cookie ,Value : [PHPSESSID=9d98c8d97660664e550f19913783c089; path=/, ci_session=a%3A0%3A%7B%7D; expires=Fri, 07-Nov-2014 18:22:29 GMT; Max-Age=-31500000; path=/, ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%228cf5e634854030668573ec1f0dc9c6d9%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884549%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D9e233ffe356e965178da38e538fd8b31; expires=Mon, 06-Nov-2017 08:22:29 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%228cf5e634854030668573ec1f0dc9c6d9%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884549%3B%7D53b1ee5e2e625d24d33a153a50881093; expires=Mon, 06-Nov-2017 08:22:29 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%228cf5e634854030668573ec1f0dc9c6d9%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884549%3B%7D53b1ee5e2e625d24d33a153a50881093; expires=Mon, 06-Nov-2017 08:22:29 GMT; Max-Age=63072000; path=/]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : Vary ,Value : [Accept-Encoding]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : X-Android-Received-Millis ,Value : [1446884547643]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : X-Android-Response-Source ,Value : [NETWORK 200]
11-07 13:52:27.651 5264-5291/projects.test.com.webviewtest I/System.out: Key : X-Android-Sent-Millis ,Value : [1446884547076]

观察: Set-Cookie 是打包在一起的,四个实例。

当我手动在Advanced Rest Client 中尝试此操作时,一切正常。我得到了所需的 HTML 页面 - 已通过身份验证。

观察: Advanced Rest Client App 只有当我在同一个浏览器中登录网站时才会给出正确的结果。所以基本上cookies被覆盖了。

观察

我厌倦了尝试从 HttpUrlConnection 获取会话 cookie,我所做的更改是加载一个 webview 并在其中登录。

其次,我设置了一个按钮来触发我的 HttpUrlConnection - 并尝试访问需要身份验证的页面。

在这个 HttpUrlConnection 里面我做了这样的事情:

 CookieManager cookieManager = CookieManager.getInstance();
            String cookie = cookieManager.getCookie(new URL("https://urlinQuestion.com").getHost());
            System.out.println("Cookie from cookie store" + cookie);
            connection.setRequestProperty("Cookie", cookie);

所以我将在 webView 中获得的 cookie 传递给 HttpUrlCONnection。有用。现在我觉得为了颠倒事件的顺序(因为我想要 cookie 来自 UrlConnection - 将它们传递给 webview)我将不得不更新 cookie 管理器。 (新航程从这里开始)

为了记录起见,我在下面添加了两个 cookie: 第一个不起作用,第二个我从 webview 方式获得并且可以工作,但我发现语义上没有区别:

PHPSESSID=a3d2367f8a5a3221e9bad1a91a34fd55; ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%221381c152699fb61d04663c9b854ecdd7%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A14%3A%22182.59.245.196%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1447140920%3B%7Ddd2c014724b9ca061b50774f1fea235d


PHPSESSID=348345a2bf9f9733037915fd36a4ad6c; 
ci_session=a%3A4%3A%7Bs%3A10%3A%22
session_id%22%3Bs%3A32%3A%2209304f814a6ed6ad726dabca74b94182%22%3Bs%3A10%3A%22
ip_address%22%3Bs%3A14%3A%22182.59.202.107%22%3Bs%3A10%3A%22
user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22
last_activity%22%3Bi%3A1447127988%3B%7D18055bfdb2d59618a324aff37a58871d

使用this工具阅读以上内容

【问题讨论】:

【参考方案1】:

我最接近的方法是使用 webview 作为登录名。然后你可以在 HttpUrlConnection 中继续你的会话,使用从 webview 获取的 cookie。 cookie 可按如下方式使用:

HttpURLConnection urlConnection = null;
try 
    urlConnection = (HttpURLConnection) url.openConnection();

    // Fetch and set cookies in requests
    CookieManager cookieManager = CookieManager.getInstance();
    String cookie = cookieManager.getCookie(urlConnection.getURL().toString());
    if (cookie != null) 
        urlConnection.setRequestProperty("Cookie", cookie);
    
    urlConnection.connect();

    // Get cookies from responses and save into the cookie manager
    List cookieList = urlConnection.getHeaderFields().get("Set-Cookie");
    if (cookieList != null) 
        for (String cookieTemp : cookieList) 
            cookieManager.setCookie(urlConnection.getURL().toString(), cookieTemp);
        
    

    InputStream in = new BufferedInputStream (urlConnection.getInputStream());
 catch (IOException e) 
    e.printStackTrace();
 finally 
    if (urlConnection != null) 
        urlConnection.disconnect();
    

【讨论】:

是的,这是我现在能做的最好的事情。虽然是替代品。【参考方案2】:

您应该在请求中发送Cookie 标头,而不是Set-Cookie。 示例请阅读https://www.rfc-editor.org/rfc/rfc6265。

当您的客户端在 HTTP response 标头中收到会话 cookie 时

Set-Cookie: PHPSESSID=e407ef64abb71b1ea2b8e4b30db76cf0; path=/

它应该将此 cookie 添加到后续 HTTP requests 标头中

Cookie: PHPSESSID=e407ef64abb71b1ea2b8e4b30db76cf0

编辑:

原生的PHPSESSID有点混乱,不过使用ci_session cookie的最后一个值应该没问题,例如来自回复

Set-Cookie ,Value : [PHPSESSID=e407ef64abb71b1ea2b8e4b30db76cf0; path=/, ci_session=a%3A0%3A%7B%7D; expires=Thu, 06-Nov-2014 16:54:57 GMT; Max-Age=-31500000; path=/, ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D5f4013e4a2edd2eb891ec8a2b8e8716e; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/, ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22caedca696344458e7aa1b4ad02b3cfa0%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.130.42%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A60%3A%22Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+5.1.1%3B+Nexus+5+Build%2FLMY48B%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446792897%3B%7Dc7eaa0945a7056db3cb9d336a02e5ecb; expires=Sun, 05-Nov-2017 06:54:57 GMT; Max-Age=63072000; path=/]

将以下标头添加到 webview 请求:

abc.put("Cookie", "ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2221d4f88af57e9c7477f48e0695bdb979%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22182.59.216.32%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A40%3A%22Apache-HttpClient%2FUNAVAILABLE+%28java+1.4%29%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1446884548%3B%7D30e2cc6561b3fb9659c7809d0c82946d");

我建议迭代SSID = map.get("Set-Cookie"),使用/(ci_session=.*?);/ 正则表达式测试每个单独的“Set-Cookie”标头,然后返回最后一个匹配项。

请注意,您 Web 视图中的 User-Agent 标头应与会话中的 user_agent 匹配。在上面的cookie中是Apache-HttpClient/UNAVAILABLE (java 1.4),看来webview用的是Dalvik/2.1.0 (Linux; U; Android 5.1.1; Nexus 5 Build/LMY48B)

【讨论】:

我同意,我没有使用字符串“Set-Cookie”,而是使用“Cookie”,但不同之处在于我正在重新发送整个字符串。让我试试你所说的。 不行,我也试过这样:for (String cookie : cookies) connection.setRequestProperty("Cookie", cookie.split(";", 2)[0]); System.out.println("Cookie" + cookie.split(";", 2)[0]); 又不行! 啊,是的。我误读了日志。当您收到多个Set-Cokie: name1=value1; path=..; domain=...Set-Cokie: name2=value2; path=..; domain=... 时,将它们作为单个标头Cookie: name1=value1; name2=value2 添加到请求中。 @User3 我更仔细地阅读了这个问题,并更新了我的答案。不幸的是,除非您同时控制这两个服务器端应用程序,否则没有好消息。 不是这样,我已经关闭了服务器端的USer代理。【参考方案3】:

java.net.CookieManager 的出色实现。

我已经实现了自己的想法。它实际上很酷。我创建了 我自己的 java.net.CookieManager 实现,它转发所有 对 WebViews 的 webkit android.webkit.CookieManager 的请求。这 表示不需要同步并且 HttpURLConnection 使用相同的 cookie 存储为 WebView。

类 WebkitCookieManagerProxy:

import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class WebkitCookieManagerProxy extends CookieManager 

    private android.webkit.CookieManager webkitCookieManager;

    public WebkitCookieManagerProxy()
    
        this(null, null);
    

    public WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy)
    
        super(null, cookiePolicy);

        this.webkitCookieManager = android.webkit.CookieManager.getInstance();
    

    @Override
    public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException 
    
        // make sure our args are valid
        if ((uri == null) || (responseHeaders == null)) return;

        // save our url once
        String url = uri.toString();

        // go over the headers
        for (String headerKey : responseHeaders.keySet()) 
        
            // ignore headers which aren't cookie related
            if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;

            // process each of the headers
            for (String headerValue : responseHeaders.get(headerKey))
            
                this.webkitCookieManager.setCookie(url, headerValue);
            
        
    

    @Override
    public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException 
    
        // make sure our args are valid
        if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");

        // save our url once
        String url = uri.toString();

        // prepare our response
        Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();

        // get the cookie
        String cookie = this.webkitCookieManager.getCookie(url);

        // return it
        if (cookie != null) res.put("Cookie", Arrays.asList(cookie));
        return res;
    

    @Override
    public CookieStore getCookieStore() 
    
        // we don't want anyone to work with this cookie store directly
        throw new UnsupportedOperationException();
    

并通过在您的应用程序初始化中执行此操作来使用它:

android.webkit.CookieSyncManager.createInstance(appContext);
// unrelated, just make sure cookies are generally allowed
android.webkit.CookieManager.getInstance().setAcceptCookie(true);

// magic starts here
WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL);
java.net.CookieHandler.setDefault(coreCookieManager);

参考:Talkol - WebkitCookieManagerProxy

【讨论】:

这不起作用,我已经阅读了这个答案,然后才发布了一个新问题。 好吧,究竟是什么不起作用?未调用回调? Webview 没有加载?会话未共享?缺少内容?我看到您使用的是 Android 5.1.1,并且带有 cookie 的 Webview 行为发生了很大变化。哪个 API 级别作为最低和目标? mixed-content/cookies 会话未维护。时期!让我们将 5.1.1 视为最小值和最大值!为了添加更多细节,我在 cookie 存储中正确设置了 cookie,并将它们返回到下一个 URlConnection 中。但不知何故,会话失败了。我在下一个 URL 连接中获得了登录 HTML。 让我们在这里根本不考虑 web 视图,让我们考虑两个 URL 连接,一个用于传递用户凭据 - 如果用户进行身份验证,则获取“Set-Cookie”值。在 cookieManager CookieManager.getInstance().setCookie 中添加这些 Cookie,然后启动新的 URL 连接 - 读取 cookie - CookieManager.getInstance().getCookie 并从此处获取原始 html。它坏了 - 让我进入登录页面。 但是,如果我使用 webview 登录,然后为该域获取 cookie,一切正常。本机 HttpUrlConnection 能够持久化会话。【参考方案4】:

尝试将这两行添加到您想要的任何位置。 (也许如果你扩展 Application 类并将它们添加到 onCreate() 方法会更好)

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

【讨论】:

嗯好的,看看这个http://***.com/a/12731212/3763848

以上是关于保持 HttpUrlConnection 调用之间的会话(本机/Webview)的主要内容,如果未能解决你的问题,请参考以下文章

两个java工程之间的相互调用方法

微服务之间相互调用方法

在 HTTPURLCONNECTION 和 WebView 之间共享创建的会话

HttpURLConnection.getResponseCode() 在第二次调用时返回 -1

Java调用Http接口--HttpURLConnection调用Http接口

Java使用HttpURLConnection调用WebService(原始方法)