【达内课程】网络通信之cookie、session、验证码(3)

news/2024/5/18 12:01:45 标签: cookie, session

文章目录

  • 概念

概念

【HTTP的状态管理】
由于 HTTP 协议是一款基于短连接的协议,所以HTTP协议是无状态的协议,我们在必要时需要实现 HTTP 协议的状态管理

无状态的意思是:服务端不保存客户端状态

【Cookie机制】
把数据保存在客户端
1、客户端发送 HTTP 协议的请求,在服务端接受并处理请求,返回响应数据包,并且在响应数据包中携带 Cookie 信息:(以消息头的形式)
Set-Cookie:cishu=10
2、客户端接受响应数据,并且解析数据包获取 cookie 信息,保存到客户端中
3、当客户端发送后续请求时,需要在请求数据包中携带 cookie 信息:(以消息头的形式)
Cookie:cishu=10
4、服务端接受请求,并且解析请求,获取 cookie 信息,执行业务,完成 HTTP 状态管理

【Cookie的限制】
1、不能存中文
2、不能存大量数据
3、安全性

【Session机制】
把数据保存在服务端
1、客户端发送 http 请求,服务端把数据存入服务端 session 对象中,并且分配一个 JSESSIONID,以 cookie 的方式返回给客户端。
Set-Cookie:JSESSIONID=ABCD
2、客户端接受响应,解析响应数据包,获取 JSESSIONID 保存到客户端。
3、当客户端发送后续请求时,需要在请求数据包中携带 JSESSIONID 一同发送该请求:(以 cookie 的方式)
Cookie:JSESSIONID=ABCD
4、服务端接受请求数据包,获取 JSESSIONID,通过 JSESSIONID 找到上次请求保存到服务端的数据,处理业务,完成 HTTP 状态管理

【验证码业务】
验证码的租用:防止机器人恶意攻击服务器
1、获取验证码请求:
服务端生成验证码图片,把正确答案存入服务端。返回验证码图片的同时也返回 JSESSIONID
2、验证码验证
发送验证码请求,并且传递正确的验证码给服务端。于此同时,需要在请求数据包中携带 JSESSIONID。服务端才可以通过 JSESSIONID 获取正确的验证码并且进行比较。

我们上一节的登录并没有保存登录的状态,需要保存登录状态,需要给服务器传会JSESSIONID,用一个栗子做一下
我们需要一个这样的布局
这里写图片描述
activity_test

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:text="用户名" />

        <EditText
            android:id="@+id/et_username"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:text="密码" />

        <EditText
            android:id="@+id/et_password"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:text="验证码" />

        <EditText
            android:id="@+id/et_captcha"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView
            android:id="@+id/img_captcha"
            android:layout_width="100dp"
            android:layout_height="50dp" />
    </LinearLayout>

    <Button
        android:id="@+id/btn_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="确定" />

</LinearLayout>

TestActivity


public class TestActivity extends Activity implements View.OnClickListener {
    private Button btn_login;
    private EditText et_username;
    private EditText et_password;
    private EditText et_captcha;
    private ImageView img_captcha;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case LOGIN_SUCCESS:
                    Toast.makeText(TestActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
                    break;
                case LOGIN_FAIL:
                    Toast.makeText(TestActivity.this, "登录失败:" + msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case HANDLER_LOAD_IMAGE_SUCCESS:
                    if (bitmap != null) {
                        img_captcha.setImageBitmap(bitmap);
                    } else {
                        img_captcha.setImageResource(R.mipmap.ic_launcher);
                    }
                    break;
            }
        }
    };

    public static final int LOGIN_SUCCESS = 1;
    public static final int LOGIN_FAIL = 2;
    public static final int HANDLER_LOAD_IMAGE_SUCCESS = 3;
    private Bitmap bitmap;
    private String JSESSIONID;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        setViews();
        //发送http请求,获取验证码图片
        new Thread() {
            @Override
            public void run() {
                try {
                    loadImage();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }

    private void setViews() {
        et_username = findViewById(R.id.et_username);
        et_password = findViewById(R.id.et_password);
        et_captcha = findViewById(R.id.et_captcha);
        img_captcha = findViewById(R.id.img_captcha);
        img_captcha.setOnClickListener(this);
        btn_login = findViewById(R.id.btn_login);
        btn_login.setOnClickListener(this);
    }

    private void loadImage() throws IOException {
        URL url = new URL("http://域名/site/captcha.html?refresh=1&format=raw&user_agent=szyapp/android");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        InputStream is = conn.getInputStream();
        //把输入流解析为Bitmap对象
        bitmap = BitmapFactory.decodeStream(is);
        //获取响应数据包中的Set-Cookie中的JSESSIONID
        String val = conn.getHeaderField("Set-Cookie");
        Log.i("JSESSIONID", val);
        JSESSIONID = val.split(";")[0];
        //把bitmap显示到Imageview,发消息给handler
        handler.sendEmptyMessage(HANDLER_LOAD_IMAGE_SUCCESS);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_login:
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            login();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }.start();
                break;
            case R.id.img_captcha:
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            loadImage();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }.start();
                break;
        }
    }

    private void login() throws IOException, JSONException {
        //1、URL
        URL url = new URL("http://域名/site/login");
        //2、HttpURLConnection
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //3、setRequestMethod  setRequestProperty()
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Cookie", JSESSIONID);
        //4、doOutPut
        conn.setDoInput(true);
        OutputStream os = conn.getOutputStream();
        //5、构建参数
        String user_name = et_username.getText().toString();
        String password = et_password.getText().toString();
        String captcha = et_captcha.getText().toString();
        String param = "user_agent=szyapp/android&user_name=" + user_name + "&password=" + password + "&verifyCode=" + captcha;
        os.write(param.getBytes("utf-8"));
        os.flush();
        //6、inputStream
        InputStream is = conn.getInputStream();
        //7、is转换成String
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = "";
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }

        String json = sb.toString();
        //7、解析json
        JSONObject obj = new JSONObject(json);
        String res = obj.getString("code");
        //8、发消息给Handler
        if (res.equals("0")) {
            //成功
            handler.sendEmptyMessage(LOGIN_SUCCESS);
        } else {
            //失败
            Message msg = new Message();
            msg.what = LOGIN_FAIL;
            msg.obj = obj.getString("message");
            handler.sendMessage(msg);
        }
    }
}

运行结果:在这里插入图片描述


http://www.niftyadmin.cn/n/1817613.html

相关文章

clearFocus()方法无效原因和解决办法

原因 清除focus其实包含2个部分的操作&#xff1a; 清除当前View的focus标志&#xff0c;并且清除它的祖先节点中存储的mFocus信息 调用DecorView的requestFocus()方法&#xff0c;重新寻找一个View&#xff0c;并将其设置为focus requestFocus()都是以先序遍历的方式,找到…

【达内课程】XML介绍

文章目录XML介绍和语法规则实体引用XML 命名规则CDATADTDXML介绍和语法规则 【介绍】 XML 指可扩展标记语言&#xff0c;被设计用来传输和存储数据。与 HTML 有些类似&#xff0c;但不同。HTML 旨在显示信息&#xff0c;而 XML 旨在传输信息。今天我们来学习一下。学习更多&am…

【达内课程】dom4j解析XML

文章目录XML 解析方式介绍如何用dom4j解析xml具体步骤XML 解析方式介绍 【DOM4J】 DOM 解析是把整篇 XML 文档都加载到内存中&#xff0c;然后使用 DOM 相关 API 对某个或某些标签进行增删改查 【PULL】 PULL 解析是使用使用事件驱动的方式&#xff0c;边读取边解析。当 PULL…

Python自制微信机器人:群发消息、自动接收好友

运营公众号也有半年了&#xff0c;今年5月份开始的&#xff0c;之前一直用一款windows工具来运营自动接受好友请求、群发文章、自动回复等操作&#xff0c;但颇有不便。 举几个场景&#xff1a; 突然在外面看到一篇文章很好&#xff0c;临时写了一篇&#xff0c;想群发一下。…

工作中用到的关于jar包的知识

文章目录什么是jar包如何创建jar包运行jar包Android Studio添加下载好的jar包第一种方式&#xff1a;add as library第二种方式什么是jar包 因为Java是编译型语言&#xff0c;源码文件是.java&#xff0c;而编译后的.class文件才是真正可以被JVM执行的字节码。如果有很多.clas…

zabbix监控部署(都是导图!)

目录 一&#xff1a;监控软件的作用 二&#xff1a;zabbix 简介 1、zabbix 概述 2、zabbix 监控原理 3、 Zabbix 6.0 新特性 &#xff08;1&#xff09;Zabbix server高可用防止硬件故障或计划维护期的停机 &#xff08;2&#xff09;Zabbix 6.0 LTS新增Kubernetes监控功…

【达内课程】pull解析xml

文章目录pull解析介绍具体步骤举例pull解析介绍 除了上一节学习的 dom4j 解析 xml&#xff0c;我们也可以使用 Android 内置的 Pull 解析器解析 XML 文件。 Pull 解析器的运行方式与 SAX 解析器相似。它也是事件触发的。Pull 解析方式让应用程序完全控制文档该怎么样被解析。…

Android人脸识别

文章目录Android自带的人脸识别API第三方提供大牛们的封装Android自带的人脸识别API Android实现人脸识别可以通过google原生自带API实现&#xff0c;只能识别静态图片&#xff0c;缺点是精度不高&#xff0c;识别信息很少&#xff0c;只有眼睛的识别 栗子 在页面上放一个按…