GVKun编程网logo

ANDROID:在Webview和httpclient之间共享会话(android与webview交互)

14

在这篇文章中,我们将带领您了解ANDROID:在Webview和httpclient之间共享会话的全貌,包括android与webview交互的相关情况。同时,我们还将为您介绍有关androidHtt

在这篇文章中,我们将带领您了解ANDROID:在Webview和httpclient之间共享会话的全貌,包括android与webview交互的相关情况。同时,我们还将为您介绍有关android HttpClient+WebView 同步cookie、Android HttpClient,DefaultHttpClient,HttpPost、android listview的item中有webview,但是点击webview会没有反应?、android okhttp和webview session共享的知识,以帮助您更好地理解这个主题。

本文目录一览:

ANDROID:在Webview和httpclient之间共享会话(android与webview交互)

ANDROID:在Webview和httpclient之间共享会话(android与webview交互)

我实际上在WebView中记录了会话.
但我也使用httpclient来发送和从网络获取数据.我在互联网上看到,无法获取WebView的内容,因此我需要使用我的httpclient从Web服务获取数据.

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

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

这是我在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();
}

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

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

__utmc=number;

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

wt3_eid=%number%number; 

wt3_sid=%number

然后我不知道该怎么做才能在我的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);

解决方法:

所以,这就是我所做的,它对我有用 –

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

现在,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;
}

android HttpClient+WebView 同步cookie

android HttpClient+WebView 同步cookie

android客户端通过httpClient或者httpUrlConnection进行登录后,为了把登录状态同步到webView中,这时需要进行cookie的同步


参考:http://segmentfault.com/a/1190000002877843


一.cookie同步方式

下面是登录线程:

public class LoginThread extends Thread{
		
	private Handler loginHandler; 
	
	public  LoginThread(Handler loginHandler) {
		this.loginHandler = loginHandler;
	}
	@Override
	public void run() 
	{
		List<String> cookieLst = new ArrayList<String>();
		HttpParams httpParams = new BasicHttpParams();
		ConnManagerParams.setMaxTotalConnections(httpParams, 5);
		ConnManagerParams.setTimeout(httpParams, 15*1000);
		HttpConnectionParams.setSoTimeout(httpParams, 10*1000);
		HttpConnectionParams.setTcpNoDelay(httpParams, true);
		HttpPost httpPost = new HttpPost("http://192.168.1.107/cookie/login.php");
		List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
		nvPairs.add(new BasicNameValuePair("name", "lisi"));
		nvPairs.add(new BasicNameValuePair("age","22"));
		nvPairs.add(new BasicNameValuePair("gender", "男"));
		
		try {
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvPairs, HTTP.UTF_8);
			httpPost.setEntity(entity);
			HttpClient httpClient =  new DefaultHttpClient();
			
			 //Cookie可能获取不到,因此有必要调用浏览器兼容模式
			HttpClientParams.setCookiePolicy(httpClient.getParams(), CookiePolicy.BROWSER_COMPATIBILITY);  
			   
			HttpResponse httpResponse = httpClient.execute(httpPost);
			if(httpResponse!=null && httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK)
			{
			 	String content = EntityUtils.toString(httpResponse.getEntity());
			 	Log.d("LOGIN", content);
			 	Header[] allHeaders = httpResponse.getAllHeaders();
			 	if(allHeaders!=null)
			 	{
			 		//获取cookie的第一种方式
			 		for (Header header : allHeaders)
			 		{
			 			Log.d("LOGIN", header.getName()+"="+header.getValue());
			 			if("Set-Cookie".equalsIgnoreCase(header.getName()))
			 			{
			 				cookieLst.add(header.getValue());
			 			}
					}
			 	}
			 	//获取cookie的第二种方式
			 	AbstractHttpClient abstractHttpClient = (AbstractHttpClient) httpClient;
			 	CookieStore cookieStore = abstractHttpClient.getCookieStore();
			 	List<Cookie> cookies = cookieStore.getCookies();
			 	for (Cookie cookie : cookies) 
			 	{
			 		Log.d("LOGIN-COOKIE", cookie.getName()+"="+cookie.getValue()+",path="+cookie.getPath()+",domain="+cookie.getDomain()+",expires="+cookie.getExpiryDate());
				}
			 	
			 	if(loginHandler!=null)
 				{
 					Message msg = new Message();
 					msg.obj = cookieLst;
 					msg.what = 200;
 					msg.setTarget(loginHandler);
 					msg.sendToTarget();
 				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

下面是WebView主页面Activity

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
public class Main extends Activity implements DownloadListener {
	
	private WebView mWebView;
	
	//extraHeaders经测试不可以同步cookie
	private Map<String, String> extraHeaders;
	
	private final String TAG = "WEB_VIEW";
	
	private final Handler loginHandler = new Handler(){
		
		@Override
		public void handleMessage(Message msg) {
			
			if(msg.what==200)
			{
				List<String> cookies =  (List<String>) msg.obj;
				if(cookies!=null)
				{	
					syncCookieToWebView(cookies);
					mWebView.loadUrl("http://192.168.1.107/cookie/read.php");
				}
			}else{
				super.handleMessage(msg);
			}
		}
		
	};
	
	@SuppressLint("SetJavaScriptEnabled") 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mWebView = (WebView) findViewById(R.id.main_webview);
		WebSettings settings = mWebView.getSettings();
		settings.setAppCacheEnabled(true);
		settings.setCacheMode(WebSettings.LOAD_DEFAULT);
		settings.setGeolocationEnabled(true);
		settings.setUseWideViewPort(true);
		settings.setSaveFormData(true);
		settings.setSavePassword(true);
		settings.setSupportZoom(false);
		settings.setLoadsImagesAutomatically(true);
		settings.setBlockNetworkImage(false);
		if(android.os.Build.VERSION.SDK_INT>=11)
		{
			settings.setEnableSmoothTransition(true);
		}
		settings.setJavaScriptCanOpenWindowsAutomatically(false);
		settings.setAllowFileAccess(false);
		settings.setJavaScriptEnabled(true);
		String userAgent = settings.getUserAgentString();
		Log.d(TAG, userAgent);
		if(android.os.Build.VERSION.SDK_INT>=14)
		{
			mWebView.setFitsSystemWindows(true);
		}
		if(mWebView.isHardwareAccelerated())
		{
			mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
		}
		mWebView.setKeepScreenOn(true);
		extraHeaders = new IdentityHashMap<String, String>();
		
		mWebView.setWebViewClient(new WebViewClient(){
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				if(view!=null && !TextUtils.isEmpty(url))
				{
					extraHeaders.put("control-cache", "no-cache,private");
					extraHeaders.put("pragma", "no-cache,no-store");
					extraHeaders.put("expires", "0");
					view.loadUrl(url, extraHeaders);
					return true;
				}
				return super.shouldOverrideUrlLoading(view, url);
			}
		});
		
		mWebView.setDownloadListener(this);
		
		//mWebView.loadUrl("http://shouji.baidu.com/software/?from=web_alad_multi");
		new LoginThread(loginHandler).start();
	}
	//销毁webView
	@Override
	protected void onDestroy() {
		super.onDestroy();
		mWebView.clearFormData();
		mWebView.clearHistory();
		mWebView.destroy();
	}
	
	//监听文件下载,WebView不会自动下载,需要我们自己构建下载代码
	@Override
	public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype, long contentLength) 
	{
		Log.d(TAG, "url="+url);
		Log.d(TAG, "userAgent="+url);
		Log.d(TAG, "contentDisposition="+contentDisposition);
		Log.d(TAG, "mimetype="+mimetype);
		Log.d(TAG, "contentLength="+contentLength);
		
		//第一种下载方式是 自定义的http工具类
		//new DownloadThread(url,contentDisposition,mimetype,contentLength).start();
		
		
		//第二种下载方式是调用系统的webView,具有默认的进度条
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setData(Uri.parse(url));
		startActivity(intent);
		
	}
	/**
	 * cookie同步
	 */
	private void syncCookieToWebView(List<String> cookies)
	{
		CookieSyncManager.createInstance(Main.this);
		CookieManager cm = CookieManager.getInstance();
		cm.setAcceptCookie(true);
		if(cookies!=null)
		{
		    for (String cookie : cookies)
		    {
			cm.setCookie("http://192.168.1.107:80",cookie);//注意端口号和域名,这种方式可以同步所有cookie,包括sessionid
		     }
		}
		CookieSyncManager.getInstance().sync();
	}
}


二.注意:平时开发中Cookie同步是最佳选项,但这并不意味着一定需要使用cookie同步,我们可以使用  token+用户id+登录时间校验码  进行同步登录


三.对于使用javaInterface进行同步登录的问题

javaInterface风险性很高,如果android平台是 4.2+比较安全,但4.2以下版本,安全性不容乐观,比如通过反射造成硬盘被读写的可能性很高!

在android 4.2中增加了 @javainterface注解,并且将公开的方法异步化,这样有效的控制了某些没必要公开的方法被无意间作为接口公开,导致js发射到硬盘的读写io类,从而发生文件被窃取,垃圾文件堆积,有害文件被下载等问题!


四.目前来说让所有人使用 4.2+以上版本可能性不大,但尽量少使用javainterface,转而使用  协议的方式,所谓协议,就是通信协议,我们可以分析url参数,从而进行webView和native代码的通信

mWebView.setWebViewClient(new WebViewClient(){
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				
			//捕获url的参数值
			
			if(url.indexOf("login")>=0)
			{
			    //客户端代码执行某部分操作----->执行完毕后通过url参数把执行结果返回webView
			    
			}else if(url.indexOf("userCenter")>=0){
			    //客户端代码执行某部分操作----->执行完毕后通过url参数把执行结果返回webView
			}
			return super.shouldOverrideUrlLoading(view, url);
			}
		});

当然,javainterface不推荐,但完全可以使用

view.loadUrl("javascript:dosometing("+"''参数''"+")");


-------------------------------2015-04-30-更新,从webView读取cookie--------------------------------

private class MyWebViewClient extends WebViewClient {

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            webview.loadUrl(url);
            return true;
        }

        public void onPageFinished(WebView view, String url) {
            CookieManager cookieManager = CookieManager.getInstance();
            String CookieStr = cookieManager.getCookie(url);
            Log.e("sunzn", "Cookies = " + CookieStr);
            super.onPageFinished(view, url);
        }

    }



Android HttpClient,DefaultHttpClient,HttpPost

Android HttpClient,DefaultHttpClient,HttpPost

我如何将字符串数据( JSONObject.toString())发送到URL.我想在util类中编写一个静态方法来执行此操作.我希望方法签名如下

public static String postData(String url,String postData)抛出SomeCustomException

字符串url的格式应该是什么

返回String是来自服务器的响应,作为json数据的字符串表示.

编辑

目前的连接工具

package my.package;
import my.package.exceptions.CustomException;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;

import org.apache.http.httpentity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;


 public class ConnectionUtil {

 public static String postData(String url,String postData)
        throws CustomException {

    // Create a new HttpClient and Post Header
    InputStream is = null;
    StringBuilder sb = null;
    String result = "";
    HttpClient httpclient = new DefaultHttpClient();

HttpPost httppost = new HttpPost();
    httppost.setHeader("host",url);

    Log.v("ConnectionUtil","opening POST connection to URI = " + httppost.getURI() + " url = " + URLDecoder.decode(url));

    try {
        httppost.setEntity(new StringEntity(postData));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);
        httpentity entity = response.getEntity();
        is = entity.getContent();

    } catch (Exception e) {
        Log.e("log_tag","Error in http connection " + e.toString());
        e.printstacktrace();
        throw new CustomException("Could not establish network connection");
    }
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is,"utf-8"),8);
        sb = new StringBuilder();
        sb.append(reader.readLine() + "\n");
        String line = "0";

        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }

        is.close();
        result = sb.toString();

    } catch (Exception e) {
        Log.e("log_tag","Error converting result " + e.toString());
        throw new CustomException("Error parsing the response");
    }
    Log.v("ConnectionUtil","Sent: "+postData);
    Log.v("ConnectionUtil","Got result "+result);
    return result;

}

}

Logcat输出

10-16 11:27:27.287: E/log_tag(4935): Error in http connection java.lang.NullPointerException
10-16 11:27:27.287: W/System.err(4935): java.lang.NullPointerException
10-16 11:27:27.287: W/System.err(4935): at org.apache.http.impl.client.AbstractHttpClient.determineTarget(AbstractHttpClient.java:496)
10-16 11:27:27.307: W/System.err(4935): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
10-16 11:27:27.327: W/System.err(4935): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
10-16 11:27:27.327: W/System.err(4935): at in.gharpay.zap.integration.ConnectionUtil.postData(ConnectionUtil.java:92)
10-16 11:27:27.327: W/System.err(4935): at in.gharpay.zap.integration.ZapTransaction$1.doInBackground(ZapTransaction.java:54)
10-16 11:27:27.327: W/System.err(4935): at in.gharpay.zap.integration.ZapTransaction$1.doInBackground(ZapTransaction.java:1)
10-16 11:27:27.327: W/System.err(4935): at android.os.AsyncTask$2.call(AsyncTask.java:185)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
10-16 11:27:27.327: W/System.err(4935): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
10-16 11:27:27.327: W/System.err(4935): at java.lang.Thread.run(Thread.java:1019)
10-16 11:27:27.327: V/log_tag(4935): Could not establish network connection

解决方法

我认为在您的代码中,基本问题是由您使用StringEntity将参数POST到网址的方式引起的.检查以下代码是否有助于使用StringEntity将数据发布到服务器.
// Build the JSON object to pass parameters
    JSONObject jsonObj = new JSONObject();
    jsonObj.put("username",username);
    jsonObj.put("data",dataValue);

    // Create the POST object and add the parameters
    HttpPost httpPost = new HttpPost(url);
    StringEntity entity = new StringEntity(jsonObj.toString(),HTTP.UTF_8);
    entity.setContentType("application/json");
    httpPost.setEntity(entity);

    HttpClient client = new DefaultHttpClient();
    HttpResponse response = client.execute(httpPost);

希望这有助于解决您的问题.谢谢.

android listview的item中有webview,但是点击webview会没有反应?

android listview的item中有webview,但是点击webview会没有反应?

listview的item中嵌套有webview,给listview设置了onclickItem的点击事件,但是当点到webview的位置时没有响应,其他位置却可以,应该怎么设置才能在点到webview的位置时也有响应?

android okhttp和webview session共享

android okhttp和webview session共享

public static OkHttpClient get(Context context){
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .cookieJar(new WebViewCookieHandler(context))
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .cache(new Cache(context.getCacheDir(), Config.REQUEST_CACHE_SIZE));
        return builder.build();
}
public class WebViewCookieHandler implements CookieJar {
    private CookieManager mCookieManager = CookieManager.getInstance();

    public Context context;

    public WebViewCookieHandler(Context context){
        this.context = context;
    }

    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
        mCookieManager.setAcceptCookie(true);
        String urlString = url.toString();
        for (Cookie cookie : cookies) {
            mCookieManager.setCookie(urlString, cookie.toString());
        }
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
            CookieSyncManager.getInstance().sync();
        }else{
            mCookieManager.flush();
        }
    }

    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        String urlString = url.toString();
        String cookiesString = mCookieManager.getCookie(urlString);
        if (cookiesString != null && !cookiesString.isEmpty()) {
            String[] cookieHeaders = cookiesString.split(";");
            List<Cookie> cookies = new ArrayList<>(cookieHeaders.length);
            for (String header : cookieHeaders) {
                cookies.add(Cookie.parse(url, header));
            }
            return cookies;
        }
        return Collections.emptyList();
    }

 

今天关于ANDROID:在Webview和httpclient之间共享会话android与webview交互的讲解已经结束,谢谢您的阅读,如果想了解更多关于android HttpClient+WebView 同步cookie、Android HttpClient,DefaultHttpClient,HttpPost、android listview的item中有webview,但是点击webview会没有反应?、android okhttp和webview session共享的相关知识,请在本站搜索。

本文标签: