功能实现

  • 使用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);// 取得默认的HttpClientDefaultHttpClient 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;
    }
    

    (注:当前版本网络请求只能异步操作)
    然后,在UserLoginTaskdoInBackground中,当睡眠结束后,我们对登录方法进行调用:

    String res = sendPost("http://www.codefrom.com/login/ajax", mEmail, mPassword);
    Log.d("CodeFromLogin", res);
    

    我们运行项目,看看日志中打印:

    没错,将Unicode转成中文之后,得到“操作成功”的返回信息!
    需要注意一点,一开始,我没有添加httpRequest.addHeader这部分的内容,得到的结果如下:

    感兴趣的同学可以尝试一下,服务器返回提示我们操作失败,缺少ajax头部信息!

  • 保存来自服务器的Cookie
    能够成功发送数据给服务器,并且服务器能响应结果,那么,我们能否获取更多内容呢?当然可以!HttpClient提供了下面的方法供我们获取Cookie:

    // 取得Cookie
    CookieStore mCookieStore = httpclient.getCookieStore();
    List<Cookie> cookies = mCookieStore.getCookies();
    

    那么,Android又是如何对Cookie进行管理的呢?

    // 设置cookie
    public static void synCookies(Context context, String url) {  CookieSyncManager.createInstance(context);  CookieManager cookieManager = CookieManager.getInstance();  cookieManager.setCookie(url, "uid=1243432");              CookieSyncManager.getInstance().sync();
    }// 清除cookie
    private 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);// 每次登录操作的时候先清除cookieremoveAllCookie();// 根据url获得HttpPost对象HttpPost httpRequest = new HttpPost(url);// 取得默认的HttpClientDefaultHttpClient 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());// 取得CookieCookieStore mCookieStore = httpclient.getCookieStore();List<Cookie> cookies = mCookieStore.getCookies();if (cookies.isEmpty()) {System.out.println("Cookies为空");} else {for (int i = 0; i < cookies.size(); i++) {// 保存cookieCookie 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() {@Overridepublic 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实现码源登录效果二相关推荐

  1. Android利用Cookie实现码源登录效果

    上一篇讲了界面的实现,详情请戳Android利用Cookie实现码源登录效果(一) - 界面实现,本篇将对功能的实现进行分析. 具体实现 功能实现 使用HttpClient进行post请求 在进行po ...

  2. Android利用贝塞尔曲线实现翻书效果(适配AndroidX)

    实现背景 不知道你有没有遇到同样的问题,要实现翻书效果,如果你是使用github上的demo或者好多博客上写的方式,你会发现,当api从28开始,会抛出Invalid Region.Op.REPLAC ...

  3. android 辅助功能 翻页,Android利用悬浮按钮实现翻页效果

    今天给大家分享下自己用悬浮按钮点击实现翻页效果的例子. 首先,一个按钮要实现悬浮,就要用到系统顶级窗口相关的WindowManager,WindowManager.LayoutParams.那么在An ...

  4. selenium利用cookie跳过验证码登录

    1.测试场景 在实现web自动化的过程中,为了解决每次登录时,验证码会随机变化的问题,以达到测试已登录状态的其他页面模块,我们需要利用cookie跳过登录,完成测试. 正常情况下,项目测试人员是不会遇 ...

  5. android布局管理器模仿qq登录效果,Android程序开发仿新版QQ锁屏下弹窗功能

    新版的qq,可以在锁屏下弹窗显示qq消息,正好目前在做的项目也需要这一功能.经过各种试验和资料查找,终于实现,过程不难,但是却有一些地方需要注意. 下面是实现过程. 1.使用Activity,而不是V ...

  6. 利用cookie免账号密码登录b站

    document.cookie ="SESSDATA=49d4147c%256557247677%2Cf295e641;domain=.bilibili.com;path=/"; ...

  7. android实现首页倒计时,android 利用CountDownTimer实现时分秒倒计时效果

    利用name或id属性设置页面跳转的锚点 理论准备         网页中的链接按照链接路径的不同,可以分为3种类型,分别是内部类型.锚点链接和外部链接:         按照使用对象的不同,网页中的 ...

  8. Android利用jsoup爬虫爬网页数据(二)

    效果图太大了,我放到github上了,想看效果的点击以下链接: 效果图一 效果图二 效果图和上文是一样的,上文只是说了一下简单的,这里的稍微麻烦一点,因为上文的基本就是个列表,而且数据结构比较简单,这 ...

  9. 【Android】zxing扫码识别及生成二维码

    在我们的生活场景中扫码已经无处不见了,微信加好友,分享......甚至在骗子的骗术里面都加入二维码这个东西.还是想在这里提醒大家不要看着什么扫描二维码抢红包,领礼品,就急急忙忙的拿起手机去扫. 今天让 ...

最新文章

  1. python集合加个逗号_8.Python集合与字符串
  2. request url换成ip地址_【协议粗讲】TTP协议之URL,不能不知道的协议技术点
  3. [APIO2015]巴厘岛的雕塑[按位贪心+dp]
  4. toj 4615 Tetrahedrons and Spheres
  5. springboot入门书籍推荐,“最粉嫩
  6. BZOJ 2431 [HAOI2009]逆序对数列 (dp)
  7. Fiddler(FD)抓包工具汉化版及使用方法
  8. 知识产权服务代理行业税收政策
  9. QuickCHM 2.6“不支持此接口”错误的解决
  10. Python 网络爬虫实现 QQ 音乐下载
  11. mongodb不等于某个值_mongodb条件查询不等于
  12. Ubuntu18.04 + RTX2080Ti + CUDA +cudnn 环境配置
  13. 2022前端面试必问的几个小问题,你学费了吗?
  14. 偏振光及其在摄影上的应用
  15. s7300的db块详细说明_西门子db数据块详解
  16. 电子计算机工作最主要特征,电子计算机最重要的工作特征是( )
  17. Mac上QQ电话录音
  18. (转)【译】优化你的手机游戏(没有延迟的,才是健康的)
  19. CentOS-7-x86_64 iso镜像的安装(Linux操作系统)
  20. c语言AT源码,51单片机读写AT24C02源代码(详细注释)

热门文章

  1. 【mysql】phpstudy8打开MySQL命令行的方法
  2. C#毕业设计——基于C#+asp.net+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码)——网络在线考试系统
  3. 什么是欠拟合现象_欠拟合和过拟合是什么?解决方法总结
  4. python 素数库_使用Python判断质数(素数)的简单方法讲解
  5. matlab exp(),matlab的exp函数
  6. 2023北华大学计算机考研信息汇总
  7. 最新综述 | 皮层内外无线神经信号记录系统为脑机接口技术注入全新血液
  8. 盘点2016最值得突击的七大海外市场:最后一年窗口期,不出海就出局!
  9. GameFramework篇:框架基本理解以及源码下载
  10. 华为和H3C--VRP基础和基本的操作