Okhttp3模拟网页登录(以学校教务网站为例)

本人android新人,学习android2个月了,最近想对学校教务网站进行分析,了解到了模拟登陆

以前对网页的内容了解挺少的,最近才学习的一些东西,有错误的地方敬请批正。


准备工具:httpwatch抓包软件(httpwatch在win10下最新版有兼容问题,我用的是7.0专业版)

okhttp3包:在AS的gradle中导入以下代码

compile 'com.squareup.okhttp3:okhttp:3.10.0'
3.10.0是我做的时候最新版,可以到okhttp的GitHub看下最新版:https://github.com/square/okhttp
okhttp官网:http://square.github.io/okhttp/

一.模拟登陆原理

网页传输的方式一般有get和post,  在httpwatch中你可以看到每个网页的传输方式

这是我校OA网站:http://myportal.sit.edu.cn/

我将账号密码填写后,先看下httpwatch得数据


仔细看每一条记录,一般都是前面一两个网页。


上面的截图我们可以看到,提交方式为POST,而POST的对象是这个网页http://myportal.sit.edu.cn/userPasswordValidate.portal

并不是我们的输入账号密码的主页,这里很重要,POST的网页不能弄错了。、

下面POST Data中,有4行数据的需要你post给网页的,提交代码可以这样写

                    OkHttpClient client = new OkHttpClient();
                    RequestBody requestBody = new FormBody.Builder()
                            .add("goto", "http://myportal.sit.edu.cn/loginSuccess.portal")
                            .add("gotoOnFail", "http://myportal.sit.edu.cn/loginFailure.portal")
                            .add("Login.Token1",username.getText().toString())
                            .add("Login.Token2",password.getText().toString())
                            .build();
                    Request request1 = new Request.Builder()
                            .url("http://myportal.sit.edu.cn/userPasswordValidate.portal")
                            .post(requestBody)
                            .build();

requestBody是提交的数据,request是提交请求,后面还回有response,就是网页返回的数据。


接下来我们继续看httpwatch抓包的内容


我们post的网页返回的header(头文件信息),头文件包含了COOKIE,但是这个cookie并不是我们想要的。

看写一个网页:


我们看到下面有个网页和登录页面网址一样的

在第一个网页登录成功后,会返回一个才cookie信息,这个cookie需要和头文件信息一起提交给第二个网页

get提交头文件信息代码:

Request request = new Request.Builder()
                            .url(LOGINURL2)
                            .header("Accept", "text/html, application/xhtml+xml, image/jxr, */*")
                            // .header("Accept-Encoding", "gzip, deflate")
                            //这样可以注释掉,不注释的话返回数据乱码
                            .header("Accept-Language", "zh-Hans-CN,zh-Hans;q=0.5")
                            .header("Connection", "Keep-Alive")
                            .header("Cookie", str)
                            .header("Host", "myportal.sit.edu.cn")
                            .header("Referer", "http://myportal.sit.edu.cn/userPasswordValidate.portal")
                            .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko")
                            .build();

好了,最重要的就是获取cookie,然后将cookie和头文件信息提交就行了,然后网页会返回登录后的界面

看下我的结果图吧,我只是获取了网页数据,并没有进行分析,写的代码都很简单,(复杂的我也不会啊亲)


如果没有登录成功的话会返回登陆界面的数据。


二.实现代码


上面都是理论,下面开始码代码啦,都是看别人写的然后自己慢慢下,有奇怪的地方见谅哦。我将代码缩短了一些,只写了输入账号密码, 然后登录按钮


布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="学号:"
            android:textSize="17dp"/>

        <EditText
            android:id="@+id/username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="输入学号"
            android:textSize="15dp"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密码:"
            android:textSize="17dp"/>
        <EditText
            android:id="@+id/password"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="输入密码"
            android:textSize="15dp"/>

    </LinearLayout>

    <Button
        android:id="@+id/send_request"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="17dp"
        android:text="send_postdata"/>

//用来显示返回的网页数据

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/response_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />


    </ScrollView>


</LinearLayout>

开启线程进行网络操作:

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    RequestBody requestBody = new FormBody.Builder()
                            .add("goto", "http://myportal.sit.edu.cn/loginSuccess.portal")
                            .add("gotoOnFail", "http://myportal.sit.edu.cn/loginFailure.portal")
                            .add("Login.Token1",username.getText().toString())
                            .add("Login.Token2",password.getText().toString())
                            .build();
                    Request request1 = new Request.Builder()
                            .url(LOGINURL1)
                            .post(requestBody)
                            .build();

                    Response response1 = client.newCall(request1).execute();
                    final Headers headers = response1.headers();
                    //   Log.d("头信息", "header " + headers);
                    HttpUrl loginUrl = request1.url();
                    // List<Cookie> cookies = Cookie.parseAll(loginUrl, headers);  这是另一种获取cookie的方法
                    cookies = headers.values("Set-Cookie");
                    Log.d("cookie信息", "onResponse-size: " + cookies);

                    if (cookies != null) {
                        save(cookies);
                        //保存cookies,不知道可不可行
                    }

                    //List<String>是String数组集合,先转换成String[],在转换成String
                    String[] strs = cookies.toArray(new String[cookies.size()]);
                    String str = null;
                    for (int i = 0; i < strs.length; ++i) {
                        str = strs[i];
                    }

                    Request request = new Request.Builder()
                            .url(LOGINURL2)
                            .header("Accept", "text/html, application/xhtml+xml, image/jxr, */*")
                            // .header("Accept-Encoding", "gzip, deflate")
                            //这样可以注释掉,不注释的话返回数据乱码
                            .header("Accept-Language", "zh-Hans-CN,zh-Hans;q=0.5")
                            .header("Connection", "Keep-Alive")
                            .header("Cookie", str)
                            .header("Host", "myportal.sit.edu.cn")
                            .header("Referer", "http://myportal.sit.edu.cn/userPasswordValidate.portal")
                            .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko")
                            .build();
                    Response response = client.newCall(request).execute();
                    String responseData = response.body().string();
                    showResponse(responseData);


                    okHttpClient.newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(okhttp3.Call call, IOException e) {
                        }
                        @Override
                        public void onResponse(okhttp3.Call call, Response response) throws IOException {
                           // Log.d("源代码", "onResponse: " + response.body().string().toString());
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

需要注意的是如何从response获取cookie,然后将List<String> cookie 转换成String类型,就可以直接上传了

                    Response response1 = client.newCall(request1).execute();
                    final Headers headers = response1.headers();
                    //   Log.d("头信息", "header " + headers);
                    HttpUrl loginUrl = request1.url();
                    // List<Cookie> cookies = Cookie.parseAll(loginUrl, headers);  这是另一种获取cookie的方法
                    cookies = headers.values("Set-Cookie");
                    Log.d("cookie信息", "onResponse-size: " + cookies);

                    if (cookies != null) {
                        save(cookies);
                        //保存cookies,不知道可不可行
                    }

                    //List<String>是String数组集合,先转换成String[],在转换成String
                    String[] strs = cookies.toArray(new String[cookies.size()]);
                    String str = null;
                    for (int i = 0; i < strs.length; ++i) {
                        str = strs[i];
                    }

完整的代码就不放出来来了,可以在下面下载。

https://download.csdn.net/download/qq_36332133/10424800


放下自己的QQandroid学习交流群:698691129

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot是一个Java开发的框架,提供了丰富的功能和便捷的开发方式。而OkHttp是一个开源的HTTP客户端,支持WebSocket协议。在Spring Boot中,我们可以使用OkHttp3模拟客户端请求WebSocket。 首先,我们需要在pom.xml文件中添加OkHttp3的依赖: ```xml <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.14.9</version> </dependency> ``` 接下来,在Spring Boot的配置文件中,我们需要配置WebSocket的相关信息,包括WebSocket的地址和消息处理器等。以下是一个示例配置: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myWebSocketHandler(), "/websocket").setAllowedOrigins("*"); } @Bean public WebSocketHandler myWebSocketHandler() { return new MyWebSocketHandler(); } } ``` 在MyWebSocketHandler类中,我们可以编写WebSocket的消息处理逻辑: ```java public class MyWebSocketHandler extends TextWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); // 处理消息 session.sendMessage(new TextMessage("Hello, " + payload)); } } ``` 最后,我们可以使用OkHttp3模拟客户端请求WebSocket。以下是一个示例代码: ```java OkHttpClient client = new OkHttpClient.Builder().build(); Request request = new Request.Builder() .url("ws://localhost:8080/websocket") .build(); WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() { @Override public void onOpen(WebSocket webSocket, Response response) { // 连接打开时的逻辑 webSocket.send("Hello, Server!"); } @Override public void onMessage(WebSocket webSocket, String text) { // 接收到消息时的逻辑 System.out.println("Received message: " + text); webSocket.close(1000, "Goodbye, Server!"); } @Override public void onFailure(WebSocket webSocket, Throwable t, Response response) { // 连接失败时的逻辑 t.printStackTrace(); } }); ``` 以上就是使用OkHttp3模拟客户端请求WebSocket的基本步骤。通过配置WebSocket和编写消息处理逻辑,我们可以实现WebSocket的双向通信。同时,使用OkHttp3可以方便地发送和接收WebSocket消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值