ANDROID:在 Webview 和 httpclient 之间共享会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11224454/
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 06:23:31  来源:igfitidea点击:

ANDROID : Share session between Webview and httpclient

androidwebviewhttpclientsession-cookies

提问by Dahevos

I have actually a logged session in my WebView. But I use also httpclient to send and get data from the web. I saw on the internet that it's impossible to get the content of a WebView, so I needed to use my httpclient to get data from a webservice.

我的 WebView 中实际上有一个记录的会话。但我也使用 httpclient 从网络发送和获取数据。我在网上看到无法获取 WebView 的内容,所以我需要使用我的 httpclient 从 Web 服务获取数据。

The problem is that this webservice uses sessions... and my session is in my WebView, so the httpclient doesn't have it and I can't access the content of the webservice.

问题是这个 webservice 使用了 session... 而我的 session 在我的 WebView 中,所以 httpclient 没有它,我无法访问 webservice 的内容。

I see many posts about this problem but I didn't understand the solution.

我看到很多关于这个问题的帖子,但我不明白解决方案。

Here is what i did on my onPageStarted :

这是我在 onPageStarted 上所做的:

CookieManager mgr = CookieManager.getInstance();
Log.i( "URL", url );
Log.i("Cookie",mgr.getCookie("mywebsite.com"));
String cookie_string = mgr.getCookie("mywebsite.com");
if(cookie_string.length() > 1) {                    
    Data.instance().getPref().edit().putString("cookie",cookie_string).commit();
}

I saw that I have this kind of things, so I hope those include session too: (i remove the number)

我看到我有这种东西,所以我希望那些也包括会话:(我删除了号码)

__utma=......(number)......; 

__utmc=number;

__utmz=number.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); 

wt3_eid=%number%number; 

wt3_sid=%number

Then i don't know what to do in order to set this cookie in my httpclient. I try that, with no success :

然后我不知道该怎么做才能在我的 httpclient 中设置这个 cookie。我试过了,没有成功:

HttpClient client = new DefaultHttpClient();
BasicCookieStore cookieStore = new BasicCookieStore();
String login_cookie_string = Data.instance().getPref().getString("cookie", "");
String[] cookie_parts = null;
if(login_cookie_string.length()> 0)
{

    //debug_view.setText(login_cookie_string);
    Log.d("COOKIE", login_cookie_string);
    cookie_parts = login_cookie_string.split(";");

    for(int t=0;t < cookie_parts.length;t++)
    {
        String[] cookieContent = cookie_parts[t].split("=");
        Cookie login_cookie = new BasicClientCookie(cookieContent[0],cookieContent[1]);
        ((BasicClientCookie) login_cookie).setDomain("mywebsite.com");
        cookieStore.addCookie(login_cookie);
    }

}
((AbstractHttpClient) client).setCookieStore(cookieStore);

回答by user2405598

So , this is what I did and it worked for me -

所以,这就是我所做的并且对我有用-

HttpRequestBase request = new HttpGet(uri);
request.addHeader("Cookie", getCookieFromAppCookieManager(uri.toString()));

Now the implmentation for the getCookieFromAppCookieManager is as follows -
The method gets the cookies for a given URL from the application CookieManager. The application CookieManager manages the cookies used by an application's WebView instances.

现在 getCookieFromAppCookieManager 的实现如下 -
该方法从应用程序 CookieManager 获取给定 URL 的 cookie。应用程序 CookieManager 管理应用程序的 WebView 实例使用的 cookie。

@param url the URL for which the cookies are requested
@return value the cookies as a string, using the format of the 'Cookie' HTTP request header
@throws MalformedURLException


public static String getCookieFromAppCookieManager(String url) throws MalformedURLException {
    CookieManager cookieManager = CookieManager.getInstance();
    if (cookieManager == null)
        return null;
    String rawCookieHeader = null;
    URL parsedURL = new URL(url);

    // Extract Set-Cookie header value from Android app CookieManager for this URL
    rawCookieHeader = cookieManager.getCookie(parsedURL.getHost());
    if (rawCookieHeader == null)
        return null;
    return rawCookieHeader;
}

回答by Dahevos

Follow this tuto :

按照这个教程:

http://metatroid.com/article/Android:%20handling%20web%20service%20authentication

http://metatroid.com/article/Android:%20handling%20web%20service%20authentication

=============================== Here the content of the webpage =====

============================== 这里是网页内容=====

Something you might find yourself doing in Android is web authentication. Most web sites issue a cookie to track session ID's and keep a user logged in. In order to maintain this authentication, you will need to keep cookies synced between activities and between http clients and webviews.

您可能会发现自己在 Android 中做的事情是 Web 身份验证。大多数网站都会发布一个 cookie 来跟踪会话 ID 并保持用户登录。为了保持这种身份验证,您需要在活动之间以及 http 客户端和 web 视图之间保持 cookie 同步。

The method I ended up doing, which seems to work well enough, was to create a class that extends Application, then define a single HttpClient to be used throughout the rest of the Application. That code looks like:

我最终采用的方法似乎很有效,它是创建一个扩展 Application 的类,然后定义一个 HttpClient 以在整个应用程序的其余部分中使用。该代码如下所示:

public class AppSettings extends Application {
    private static final DefaultHttpClient client = createClient();

    @Override
    public void onCreate(){
    }

    static DefaultHttpClient getClient(){
            return client;
    }
    private static DefaultHttpClient createClient(){
            BasicHttpParams params = new BasicHttpParams();
            SchemeRegistry schemeRegistry = new SchemeRegistry();
            schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
            schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
            ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
            DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);
            httpclient.getCookieStore().getCookies();
            return httpclient;
    }

This class also creates an HttpClient that is suitable for AsyncTasks and making multiple simultaneous http requests. Using ThreadSafeClientConnManager for the ClientConnectionManager let's you run http requests inside AsyncTasks without causing a force close when you press the back button and start a second, or third.

该类还创建了一个适用于 AsyncTasks 并同时发出多个 http 请求的 HttpClient。为 ClientConnectionManager 使用 ThreadSafeClientConnManager 可以让您在 AsyncTasks 内运行 http 请求,而不会在您按下后退按钮并启动第二个或第三个时导致强制关闭。

It also creates a single default cookie store that can be accessed in all your activities. You would use this in your other activities by calling the getClient() method.

它还创建了一个可以在您的所有活动中访问的默认 cookie 存储。您可以通过调用 getClient() 方法在其他活动中使用它。

For example

例如

public class SomeActivity extends Activity {
        static DefaultHttpClient mClient = AppSettings.getClient();
        ...
        try {

            HttpGet httpget = new HttpGet('URL');
            HttpResponse response;
            response = mClient.execute(httpget);
            ...
        }
        ...
    }

If you find it necessary to use a webview and need it to access and use the same cookies as your client. You can sync the client's cookie store using CookieManager: (in onPageStarted method)

如果您发现有必要使用 webview 并且需要它访问和使用与您的客户端相同的 cookie。您可以使用 CookieManager 同步客户端的 cookie 存储:(在 onPageStarted 方法中)

DefaultHttpClient mClient = AppSettings.getClient();


Cookie sessionInfo;
List<Cookie> cookies = mClient.getCookieStore().getCookies();

if (! cookies.isEmpty()){
        CookieSyncManager.createInstance(getApplicationContext());
        CookieManager cookieManager = CookieManager.getInstance();

        for(Cookie cookie : cookies){
                sessionInfo = cookie;
                String cookieString = sessionInfo.getName() + "=" + sessionInfo.getValue() + "; domain=" + sessionInfo.getDomain();
                cookieManager.setCookie("example.com", cookieString);
                CookieSyncManager.getInstance().sync();
        }
}

You will need to switch example.com with the correct domain.

您将需要使用正确的域切换 example.com。