码迷,mamicode.com
首页 > 其他好文 > 详细

模拟登陆、Cookie传递

时间:2016-05-13 23:17:07      阅读:295      评论:0      收藏:0      [点我收藏+]

标签:

---恢复内容开始---

上个月月底把模拟登陆的问题解决了,现在有时间就正好记录并复习一下。

主要使用httpclient 来进行模拟登陆 

 

首先做一个登陆布局  一直以来都是简单拖几个控件 没有啥特效  这次我想使用一点 Material Design设计风格    查了一下 TextInputLayout这个控件  还不错 

TextInputLayout 来自于 Android Design Support Library    可以让edittext的hint在用户输入的时候  自动跳到上方   效果挺好看的  

用法也很简单 TextInputLayout  在布局文件中 直接包裹住 edittext就行了    TextInputLayout 也要起个id  在activity里要设置hint   此时在edittext里面设置hint没有用

<android.support.design.widget.TextInputLayout
    android:id="@+id/usernameWrapper"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
<EditText
    android:id="@+id/username"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:maxLines="1"
    />
</android.support.design.widget.TextInputLayout>

  

登陆界面代码

技术分享
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:paddingBottom="@dimen/activity_vertical_margin"
 7     android:paddingLeft="@dimen/activity_horizontal_margin"
 8     android:paddingRight="@dimen/activity_horizontal_margin"
 9     android:paddingTop="@dimen/activity_vertical_margin"
10     tools:context=".LoginActivity"
11     android:orientation="vertical"
12     >
13 
14 
15 
16    <RelativeLayout
17        android:layout_width="match_parent"
18        android:layout_height="wrap_content"
19         android:layout_weight="0.4"
20        >
21 
22        <TextView
23            android:layout_width="match_parent"
24            android:layout_height="wrap_content"
25            android:text="网络舆情防控处置系统"
26            android:gravity="center"
27            android:layout_centerInParent="true"
28            android:textSize="30sp"
29            android:textColor="#333333"
30            />
31    </RelativeLayout>
32 
33 
34 <LinearLayout
35     android:layout_width="match_parent"
36     android:layout_height="wrap_content"
37     android:layout_weight="0.7"
38     android:orientation="vertical"
39     >
40 
41     <android.support.design.widget.TextInputLayout
42         android:id="@+id/usernameWrapper"
43         android:layout_width="match_parent"
44         android:layout_height="wrap_content" >
45     <EditText
46         android:id="@+id/username"
47         android:layout_width="match_parent"
48         android:layout_height="wrap_content"
49         android:maxLines="1"
50         />
51     </android.support.design.widget.TextInputLayout>
52 
53     <android.support.design.widget.TextInputLayout
54         android:id="@+id/passwordWrapper"
55         android:layout_width="match_parent"
56         android:layout_height="wrap_content"
57         android:layout_marginTop="4dp" >
58     <EditText
59         android:id="@+id/password"
60         android:layout_width="match_parent"
61         android:layout_height="wrap_content"
62         android:inputType="textPassword"
63         android:maxLines="1"
64         />
65     </android.support.design.widget.TextInputLayout>
66 
67     <CheckBox
68         android:id="@+id/cb"
69         android:text="记住账号密码"
70         android:layout_width="wrap_content"
71         android:layout_height="wrap_content" />
72 
73     <Button
74         android:id="@+id/btn"
75         android:layout_width="match_parent"
76         android:layout_height="wrap_content"
77         android:text="登陆"
78         />
79 </LinearLayout>
80 </LinearLayout>
login

 

在activity中  sethint就行了    运行起来就能看到效果了     

usernameWrapper=(TextInputLayout) findViewById(R.id.usernameWrapper);
passwordWrapper=(TextInputLayout) findViewById(R.id.passwordWrapper);

usernameWrapper.setHint("账号");
passwordWrapper.setHint("密码");

 

登陆按钮判断一下输入框是否为空 

if (TextUtils.isEmpty(str_username.trim())||TextUtils.isEmpty((str_password).trim()) ){
Toast.makeText(getApplicationContext(), "用户名或密码不能为空", Toast.LENGTH_LONG).show();
}else {
Login(str_username,str_password);
}

新建login方法   

HttpClient是一个接口  先要创建一个实例 DefaultHttpClient defaultclient = new DefaultHttpClient();

创建一个HttpPost对象,传入目标的网络地址  HttpPost httpPost = new HttpPost("网络地址");

最后就是 访问的结果  HttpResponse  httpResponse = defaultclient.execute(httpPost);

 

由于这里要登陆  所以账号密码必须作为参数传递过去   通过一个NameValuePair集合来存放  

把这个参数集合传入到一个UrlEncodedFormEntity中  然后调用HttpPost的setEntity()方法将构建好的UrlEncodedFormEntity传入

List<NameValuePair>params=newArrayList<NameValuePair>();

Params.add(new BasicNameValuePair(“username”,”admin”));

Params.add(new BasicNameValuePair(“password”,”123456”));

 

httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

或者:

UrlEncodedFormEntity entity=newUrlEncodedFormEntity(params,”utf-8”);    

httpPost.setEntity(entity);

 

访问网站会产生cookies  它就相当于人的身份证  没有它  就无法证明自己是谁  这在后面是有用处的   HttpClient 有方法可以取出它

List mCookies = defaultclient.getCookieStore().getCookies();

cookies  的两个必要值  name value 是我的目标    我取出来的方法是  先打印出来看看cookies   看清楚值的位置  用substring取出

String cook=mCookies.toString();
cookname = cook.substring(cook.indexOf("name: ")+6,cook.indexOf("][value"));
cookvalue = cook.substring(cook.indexOf("value: ")+7,cook.indexOf("][domain"));

 

请求发送成功之后  取得返回结果

if (httpResponse.getStatusLine().getStatusCode() == 200){
HttpEntity entity = httpResponse.getEntity();
String MAINBODYHTML = EntityUtils.toString(entity);
IsLoginSuccessful(MAINBODYHTML);
}

 

技术分享
 1     private void Login(final String username, final String password){
 2         new Thread(new Runnable() {
 3 
 4             @Override
 5             public void run() {
 6                 DefaultHttpClient defaultclient = new DefaultHttpClient();
 7                 HttpPost httpPost = new HttpPost("登陆网站");
 8                 HttpResponse httpResponse;
 9 
10                 List<NameValuePair> params = new ArrayList<NameValuePair>();
11                 params.add(new BasicNameValuePair("username", username));
12                 params.add(new BasicNameValuePair("password", password));
13 
14                 try {
15                     httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
16                     httpResponse = defaultclient.execute(httpPost);
17                     Log.i("xyz", String.valueOf(httpResponse.getStatusLine().getStatusCode()));
18 
19                     List mCookies = defaultclient.getCookieStore().getCookies();
20                     Log.d("cookies", mCookies.toString() );
21                   //  List<Cookie> cookies = defaultclient.getCookieStore().getCookies();
22                    // Log.d("cookies", cookies.toString() );
23 
24                     String cook=mCookies.toString();
25                     cookname = cook.substring(cook.indexOf("name: ")+6,cook.indexOf("][value"));
26                     cookvalue = cook.substring(cook.indexOf("value: ")+7,cook.indexOf("][domain"));
27 
28                     Log.d("cookies", cookname +"++++"+ cookvalue);
29 
30                     if (httpResponse.getStatusLine().getStatusCode() == 200){
31                         StringBuffer sb = new StringBuffer();
32                         HttpEntity entity = httpResponse.getEntity();
33                         String MAINBODYHTML = EntityUtils.toString(entity);
34                         IsLoginSuccessful(MAINBODYHTML);
35                     }
36                 } catch (UnsupportedEncodingException e) {
37                     e.printStackTrace();
38                 } catch (ClientProtocolException e) {
39                     e.printStackTrace();
40                 } catch (IOException e) {
41                     e.printStackTrace();
42                 }
43 
44 
45             }
46         }).start();
47     }
Login


如何判断登陆成功失败 IsLoginSuccessful方法   思路如下:网页上登陆失败会跳转到一开始的登陆页面,成功的话会进入系统,前者的网页源代码中 肯定会 “账号” “密码”等字段,同理后者的网页源代码中也一定会成功页面的那些特有字段,我就来判断登陆成功的网页源代码中是否有成功时才有的“有害信息”,如果有 说明登陆成功,没有就说明失败

这里就要使用Jsoup了

Jsoup.parse方法可以解析HTML字符串   而我们都知道网页源代码都是 html 标签打头的 所以直接select html 就可以得到网页源代码

 再用indexOf 判断是否有证明登陆成功的字段   没有就提示登陆失败   有就sendMessage  跳转activity 并带上 cookies的两个必要值  这里不能直接跳转 而且Toast前后都要加上Looper.prepare();和Looper.loop();

 

技术分享
 1 private void IsLoginSuccessful(String result){
 2         Document doc= Jsoup.parse(result);
 3 
 4         Element masthead = doc.select("html").first();
 5 
 6           if (masthead.toString().indexOf("有害信息")!=-1){
 7               if (checkBox.isChecked()){
 8                   editor.putString("username",str_username);
 9                   editor.putString("password",str_password);
10                   editor.commit();
11               }
12 
13               Message msg=new Message();
14               msg.arg1=1;
15               handler.sendMessageDelayed(msg,200);
16 
17         }else{
18               Looper.prepare();
19               Toast.makeText(getApplicationContext(),"登陆失败",Toast.LENGTH_LONG).show();
20               Looper.loop();
21 
22           }
23 
24     }
IsLoginSuccessful
技术分享
 1     private Handler handler=new Handler(){
 2       public void handleMessage(android.os.Message msg){
 3           Toast.makeText(getApplicationContext(),"登陆成功",Toast.LENGTH_SHORT).show();
 4           Intent in=new Intent(LoginActivity.this,MainActivity.class);
 5           in.putExtra("name",cookname);
 6           in.putExtra("value",cookvalue);
 7           startActivity(in);
 8           finish();
 9       };
10     };
Message

 

如果没有cookies  在模拟点击系统里面的链接的话  会直接跳转到登陆界面  有了cookies 之后才能保证登陆状态

后面的网络访问 我直接用的 jsoup   这个一定要带cookies参数  方法如下

Document doc = Jsoup.connect("访问网址").cookie(name, value).timeout(5000).get();

 

现在就写到这里    此方法在android开发中不常用   常规开发肯定有接口   所以还是记下来  以免忘了难找

 

模拟登陆、Cookie传递

标签:

原文地址:http://www.cnblogs.com/demon9/p/5491250.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!