Android利用Cookie实现码源登录效果二
来源:互联网 发布:mac 命令行安装wget 编辑:程序博客网 时间:2024/06/16 22:58
功能实现
使用HttpClient进行post请求
在进行post请求的时候,我们先看看网页版登录是如何发送数据的。打开登录页面,点击键盘上的F12,在
Sources
中找到login
,找到发送ajax请求进行登录的部分,加入断点:点击登录,然后在
Network
中看到有个发送到http://www.codefrom.com/login/ajax 的网络请求,点开它,我们看看Header里面有什么数据:可以看到,有三部分数据:
Request URL
、Request Header
和Form Data
,他们的含义我想大家应该都很清楚。那么我们就尝试在LoginActivity
中模拟一下这个操作。首先,我们写一个方法,封装我们的登录请求:
public String sendPost(String url, String username, String password) { // 根据url获得HttpPost对象 HttpPost httpRequest = new HttpPost(url); // 取得默认的HttpClient DefaultHttpClient httpclient = new DefaultHttpClient(); String strResult = null; // NameValuePair实现请求参数的封装 List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("_tk", "codefrom")); params.add(new BasicNameValuePair("name", username)); params.add(new BasicNameValuePair("pass", password)); httpRequest.addHeader("Accept", "application/json, text/javascript, */*; q=0.01"); httpRequest.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httpRequest.addHeader("Origin", "http://www.codefrom.com"); httpRequest.addHeader("Referer", "http://www.codefrom.com/login"); httpRequest.addHeader("X-Requested-With", "XMLHttpRequest"); try { // 添加请求参数到请求对象 httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); // 获得响应对象 HttpResponse httpResponse = httpclient.execute(httpRequest); // 判断是否请求成功 if (httpResponse.getStatusLine().getStatusCode() == 200) { // 获得响应返回Json格式数据 strResult = EntityUtils.toString(httpResponse.getEntity()); return strResult; } else { strResult = "错误响应:" + httpResponse.getStatusLine().toString(); } } catch (ClientProtocolException e) { strResult = "错误响应:" + e.getMessage().toString(); e.printStackTrace(); return strResult; } catch (IOException e) { strResult = "错误响应:" + e.getMessage().toString(); e.printStackTrace(); return strResult; } catch (Exception e) { strResult = "错误响应:" + e.getMessage().toString(); e.printStackTrace(); return strResult; } return strResult;}
(注:当前版本网络请求只能异步操作)
然后,在UserLoginTask
的doInBackground
中,当睡眠结束后,我们对登录方法进行调用:String res = sendPost("http://www.codefrom.com/login/ajax", mEmail, mPassword);Log.d("CodeFromLogin", res);
我们运行项目,看看日志中打印:
没错,将Unicode转成中文之后,得到“操作成功”的返回信息!
需要注意一点,一开始,我没有添加httpRequest.addHeader
这部分的内容,得到的结果如下:
感兴趣的同学可以尝试一下,服务器返回提示我们操作失败,缺少ajax头部信息!保存来自服务器的Cookie
能够成功发送数据给服务器,并且服务器能响应结果,那么,我们能否获取更多内容呢?当然可以!HttpClient
提供了下面的方法供我们获取Cookie:// 取得CookieCookieStore mCookieStore = httpclient.getCookieStore();List<Cookie> cookies = mCookieStore.getCookies();
那么,Android又是如何对Cookie进行管理的呢?
// 设置cookiepublic static void synCookies(Context context, String url) { CookieSyncManager.createInstance(context); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setCookie(url, "uid=1243432"); CookieSyncManager.getInstance().sync(); }// 清除cookieprivate void removeCookie(Context context) { CookieSyncManager.createInstance(context); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.removeAllCookie(); CookieSyncManager.getInstance().sync(); }
接下来,我们就可以对
sendPost
方法进行一些改造了:public CookieManager cookieManager = null;public static String cookies;public String sendPost(String url, String username, String password) { CookieSyncManager.createInstance(LoginActivity.this); // 每次登录操作的时候先清除cookie removeAllCookie(); // 根据url获得HttpPost对象 HttpPost httpRequest = new HttpPost(url); // 取得默认的HttpClient DefaultHttpClient httpclient = new DefaultHttpClient(); String strResult = null; // NameValuePair实现请求参数的封装 List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("_tk", "codefrom")); params.add(new BasicNameValuePair("name", username)); params.add(new BasicNameValuePair("pass", password)); httpRequest.addHeader("Accept", "application/json, text/javascript, */*; q=0.01"); httpRequest.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httpRequest.addHeader("Origin", "http://www.codefrom.com"); httpRequest.addHeader("Referer", "http://www.codefrom.com/login"); httpRequest.addHeader("X-Requested-With", "XMLHttpRequest"); try { // 添加请求参数到请求对象 httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); // 获得响应对象 HttpResponse httpResponse = httpclient.execute(httpRequest); // 判断是否请求成功 if (httpResponse.getStatusLine().getStatusCode() == 200) { // 获得响应返回Json格式数据 strResult = EntityUtils.toString(httpResponse.getEntity()); // 取得Cookie CookieStore mCookieStore = httpclient.getCookieStore(); List<Cookie> cookies = mCookieStore.getCookies(); if (cookies.isEmpty()) { System.out.println("Cookies为空"); } else { for (int i = 0; i < cookies.size(); i++) { // 保存cookie Cookie cookie = cookies.get(i); Log.d("Cookie", cookies.get(i).getName() + "=" + cookies.get(i).getValue()); cookieManager = CookieManager.getInstance(); String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain(); cookieManager.setCookie("http://www.codefrom.com/", cookieString); } } return strResult; } else { strResult = "错误响应:" + httpResponse.getStatusLine().toString(); } } catch (ClientProtocolException e) { strResult = "错误响应:" + e.getMessage().toString(); e.printStackTrace(); return strResult; } catch (IOException e) { strResult = "错误响应:" + e.getMessage().toString(); e.printStackTrace(); return strResult; } catch (Exception e) { strResult = "错误响应:" + e.getMessage().toString(); e.printStackTrace(); return strResult; } return strResult;}private void removeAllCookie() { cookieManager = CookieManager.getInstance(); cookieManager.removeAllCookie(); CookieSyncManager.getInstance().sync(); }
运行改造之后的代码,我们先进行登录,然后点击按钮打开码源首页,可以看到,首页导航是可以看到登录信息的!
使用本地广播更新界面
完成登录之后,我们需要修改主界面的控件文字,比如我们想显示用户名等等。理论上来讲,使用startActivity
将数据通过Intent从登录界面传递给主界面的方法是可行的。但是,我们需要考虑在实际中,如果多个地方校验到用户没有登录,都需要弹出登录界面,然后登录完了之后,我们需要返回的界面不一定都是主界面(如果PM要求返回主界面,当我没说),那我们该怎么办呢?
这时,我们可以通过本地广播来实现:在主界面(或者其他需要得到登录信息的界面),动态注册一个本地广播,通过广播获取到的Intent来进行数据分析,部分代码如下:localBroadcastManager = LocalBroadcastManager.getInstance(MainActivity.this);IntentFilter intentFilter = new IntentFilter();intentFilter.addAction("com.codefrom.broadcastreceiver.LOGIN_BROADCAST");//建议把它写一个公共的变量,这里方便阅读就不写了。loginBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); boolean result = bundle.getBoolean("result"); String user = bundle.getString("username"); if (result) { username.setText(user); Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show(); loginbtn.setText("退出登录"); isLogin = true; } else { Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show(); username.setText("未登录"); loginbtn.setText("登录"); isLogin = false; } }};localBroadcastManager.registerReceiver(loginBroadcastReceiver, intentFilter);
同时,在登录界面,登录成功之后,我们可以发送一个广播告知其他界面登录结果,由于登录在子线程中进行,我们就需要借助
Handler
进行广播发送:Handler handler = new Handler() {public void handleMessage(android.os.Message msg) { LoginInfo loginInfo = (LoginInfo) msg.obj; Toast.makeText(LoginActivity.this, loginInfo.getStatus() + " - " + loginInfo.getMsg() + " - " + Uri.decode(loginInfo.getMsg()) , Toast.LENGTH_SHORT).show(); if("1".equals(loginInfo.getStatus())) { Intent intent = new Intent("com.codefrom.broadcastreceiver.LOGIN_BROADCAST"); Bundle bundle = new Bundle(); bundle.putBoolean("result", true); bundle.putString("username", "单车武士"); intent.putExtras(bundle); localBroadcastManager.sendBroadcast(intent); }};};
其实,如果观察
LoginActivity
,在成功以后,它做的操作是调用Activity的finish()
,也就是直接关闭登录界面了,我猜系统应该也是不推荐直接使用startActivity进行显示跳转的。
由于服务器并没有给我们返回更多用户的信息,我们先返回一个写死的username过去……当然,在网页中是根据cookie来获取用户信息的,这方面的东西在Android上面的实现我们今后再探讨。
以上就是我们实现的模拟登录码源效果,如果有什么不对的地方或者更好的建议,欢迎回复交流。
- Android利用Cookie实现码源登录效果二
- 利用cookie实现自动登录
- Servlet与filter实现:利用Cookie实现两周内不用重复登录的效果
- Servlet与filter实现:利用Cookie实现两周内不用重复登录的效果
- Servlet学习:利用Cookie实现两周内不用重复登录的效果
- 利用cookie+session实现自动登录
- Java利用Cookie实现自动登录
- JavaWeb_利用Cookie技术实现自动登录
- phantomJS利用cookie实现自动登录
- android学习笔记之利用AsyncHttpClient实现登录及cookie使用
- android学习笔记之利用AsyncHttpClient实现登录及cookie使用
- 利用cookie自动登录
- 利用cookie的跨域单点登录的简单实现
- 利用Cookie实现自动登录,尽量做到安全
- 跨域名sso单点登录、利用p3p实现cookie跨域
- 利用cookie实现用户自动登录的代码
- 利用过滤器和cookie实现简单的单点登录
- python利用cookie模拟登录
- Nginx安装手册
- android 面试总结(2)
- CentOS 7卸载openjdk
- Land oj 1604 - Play Apple (博弈)
- [Web API] Client 指定請求及回應格式(xml/json)
- Android利用Cookie实现码源登录效果二
- 解决Ubuntu下chrome总是在Dock上留两个图标
- leetcode---Valid Palindrome
- 第七课 可执行程序的装载(2)
- 1005 hdoj Number Sequence (java函数格式)
- 记录一次Centos7下php无法连接redis
- C语言循环数组做FIFO队列--一些认识
- android多线程下载
- bestcoder 79 Claris and XOR