Glide结合OkHttp保证短信验证接口携带图形验证码接口返回Cookie值去做网络请求

news2024/12/27 13:50:52

一、实现效果

在这里插入图片描述

二、步骤

注意:仅展示核心部分代码

1、导入依赖

api 'com.github.bumptech.glide:glide:4.10.0'
kapt 'com.github.bumptech.glide:compiler:4.10.0'
api 'com.squareup.okhttp3:okhttp:3.11.0'
api 'com.squareup.okhttp3:logging-interceptor:3.11.0'

2、自定义MyAppGlideModule类

自定义Okhttp的cookie管理,在Okhttp初始化的时候设置进去。并在Glide中注册请求对象。

因为发送短信的请求需要利用图形验证码请求的cookie,所以cookie管理的逻辑就是,保存上一次请求的cookie,下一次请求的时候利用上一次请求的cookie。

大概业务流程原理如图所示:
在这里插入图片描述
代码如下:

package com.custom.jfrb.http;

import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.AppGlideModule;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
//......

@GlideModule
public class MyAppGlideModule extends AppGlideModule {

    public static OkHttpClient okHttpClient;

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        okHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookiesManager())
                .build();
        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
    }

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }

    /**
     * Cookie管理类
     */
    private class CookiesManager implements CookieJar {

        //保存每个url的cookie
        private HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();

        //上一个请求url
        private HttpUrl url;

        @Override
        public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
            //保存链接的cookie
            cookieStore.put(httpUrl, list);
            //保存上一次的url,供给下一次cookie的提取。
            url = httpUrl;
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl httpUrl) {

            //加载上一个链接的cookie
            List<Cookie> cookies = cookieStore.get(url);
            return cookies != null ? cookies : new ArrayList<Cookie>();
        }
    }
}

3、自定义输入图形验证码弹窗Dialog

package com.custom.jfrb.ui.jfrb.login;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;

@SuppressLint("ValidFragment")
public class SMSCheckDialog extends DialogFragment {

    private ImageView ivCode;
    private SMSCheckCallback checkCallback;
    //手机号
    private String phone;
    //账号名
    private String account;

	//可以把请求短信验证码接口时候需要的接口参数通过构造方法传进来
    public SMSCheckDialog(SMSCheckCallback callback, String phone,String account) {
        this.checkCallback = callback;
        this.phone = phone;
        this.account = account;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NORMAL, R.style.CustomDialog);
        setCancelable(false);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dialog_sms_check, container, false);
        ImageView ivDelete = view.findViewById(R.id.iv_delete);
        ivCode = view.findViewById(R.id.iv_code);
        ivCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	//加载图形验证码
                loadCapture();
            }
        });
        loadCapture();
        final EditText etCode = view.findViewById(R.id.et_code);
        ivDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	//关闭图形验证码弹窗
                dismiss();
            }
        });
        Button ivSure = view.findViewById(R.id.iv_login);
        ivSure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TextUtils.isEmpty(etCode.getText().toString())) {
                    RnToast.showToast(getContext(),"请输入图形验证码");
                    return;
                }
                //图形验证码输入完成后,发送短信验证码请求
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                    	//去请求发送短信验证码
                        getSmsCode(account,phone,etCode.getText().toString());
                    }
                }).start();

            }
        });
        return view;
    }


    /**
     * 加载显示图形验证码URL
     */
    private void loadCapture(){
        if (getContext() != null) {
            Log.e("mylog","执行loadCapture请求");
            String url = UserService.getImageCodeURL();
            Glide.with(getContext())
                    .load(url)
                    .skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(ivCode);
        }
    }

    /**
     * 请求短信验证码
     * @param account 账户
     * @param phone 手机号码
     * @param imageCode 图片验证码
     */
    private void getSmsCode(String account,String phone,String imageCode){
        Map<String,Object> map = new HashMap<>();
        map.put("userName",account);
        map.put("telephone",phone);
        map.put("captchaCheckCode",imageCode);
        JSONObject jsonObject = new JSONObject(map);

        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(jsonObject.toString(),JSON);

        String url = "网络请求地址......";
        Log.d("mylog_sms: ","短信验证码获取请求参数:"+"_账号:"+account+"_手机号:"+phone+"_验证码:"+imageCode);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        MyAppGlideModule.okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.d("mylog_sms: ","短信验证码接口请求失败"+e.toString());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.d("mylog_sms: ","短信验证码请求成功"+response.toString());
                if (response == null){
                    Log.d("mylog_sms: ","请求失败!");
                    checkCallback.onGetCodeFailed(getString(R.string.send_fail));
                    dismiss();
                    return;
                }
                if (response.body() == null){
                    Log.d("mylog_sms: ","请求失败!");
                    checkCallback.onGetCodeFailed(getString(R.string.send_fail));
                    dismiss();
                    return;
                }
                String result = response.body().string();

                JSONObject object = (JSONObject) JSONObject.parse(result);
                Log.d("mylog_sms: ","接受短信验证码接口返回数据:"+object);
                if ((int)object.get("code") == 0){
                    Log.d("mylog_sms: ","验证成功!");
                    checkCallback.onGetCode();
                }else{
                    Log.d("mylog_sms: ","验证错误");
                    checkCallback.onGetCodeFailed(object.get("msg").toString());
                }
                dismiss();
            }
        });

    }

    public interface SMSCheckCallback {
        void onGetCode();
        void onGetCodeFailed(String msg);
    }
}

4、相关布局文件

styles.xml文件中放入如下自定义Style

<style name="CustomDialog" parent="android:style/Theme.Dialog">
        <!--背景颜色及和透明程度-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!--是否去除标题 -->
        <item name="android:windowNoTitle">true</item>
        <!--是否去除边框-->
        <item name="android:windowFrame">@null</item>
        <!--是否浮现在activity之上-->
        <item name="android:windowIsFloating">true</item>
        <!--是否模糊-->
        <item name="android:backgroundDimEnabled">true</item>
    </style>

Dialog图形验证码验证弹窗的布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@drawable/shape_white_8">

        <ImageView
            android:id="@+id/iv_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="12dp"
            android:src="@drawable/close"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="24dp"
            android:layout_marginTop="20dp"
            android:layout_marginEnd="10dp"
            android:text="请输入图形验证码"
            android:textColor="#999999"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/iv_delete" />

        <ImageView
            android:id="@+id/iv_code"
            android:layout_width="70dp"
            android:layout_height="28dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="24dp"
            android:scaleType="fitXY"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_text" />

        <EditText
            android:id="@+id/et_code"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="24dp"
            android:layout_marginEnd="8dp"
            android:textColor="@color/color_222222"
            android:textSize="16sp"
            android:hint="@string/enter_image_code"
            android:paddingTop="10dp"
            android:paddingBottom="5dp"
            android:background="@drawable/edittext_bg"
            android:textCursorDrawable="@drawable/edit_text_cursor"
            android:textColorHint="@color/color_D5D5D5"
            android:inputType="text"
            android:maxLength="4"
            app:layout_constraintBottom_toBottomOf="@+id/iv_code"
            app:layout_constraintEnd_toStartOf="@id/iv_code"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/iv_code" />
        <Button
            android:id="@+id/iv_login"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginTop="36dp"
            android:layout_marginBottom="36dp"
            android:layout_marginStart="36dp"
            android:layout_marginEnd="36dp"
            android:background="@drawable/shape_jfrb_login_button"
            android:textColor="@color/white"
            android:text="@string/login_confirm"
            android:textSize="@dimen/sp_16"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/iv_code" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

三、使用

图形验证码输入弹窗的调用

//图形验证码校验
SMSCheckDialog checkDialog = new SMSCheckDialog(new SMSCheckDialog.SMSCheckCallback() {
        @Override
        public void onGetCode() {
            //短信验证码接口请求成功
            countdown();
        }

        @Override
        public void onGetCodeFailed(String msg) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //短信验证码接口请求失败
                }
            });
        }
    }, phone,account);
    checkDialog.show(getSupportFragmentManager(), "SMSCheckDialog");

发送短信验证码成功后等待间隙的60s倒计时文字显示

 private void countdown() {
        final long count = 60L;
        Observable.intervalRange(0, 61, 0, 1, TimeUnit.SECONDS)
                .map(new Function<Long, Long>() {
                    @Override
                    public Long apply(Long aLong) throws Exception {
                        return count - aLong;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
//                        addSubscribe(d);
                    }

                    @SuppressLint("SetTextI18n")
                    @Override
                    public void onNext(Long aLong) {
                        mTvGetCode.setText(aLong + "s");
                        mTvGetCode.setEnabled(false);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        mTvGetCode.setText(getString(R.string.change_phone9));
                        mTvGetCode.setEnabled(true);
                    }
                });
    }

附:参考Glide结合Okhttp做cookie管理实现注册需求的图片验证码短信验证码功能

四、完成,Nice!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1265653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Web】BJDCTF 2020 个人复现

目录 ①easy_md5 ②ZJCTF&#xff0c;不过如此 ③Cookie is so subtle! ④Ezphp ⑤The Mystery of IP ①easy_md5 ffifdyop绕过SQL注入 sql注入&#xff1a;md5($password,true) 右键查看源码 数组绕过 ?a[]1&b[]2 跳转到levell14.php 同样是数组绕过 param1[…

C语言第三十六弹--实现转移表的多种方法

使用C语言通过多种方法实现转移表 方法一、普通法 思路&#xff1a;如图实现多种操作&#xff0c;首先创建菜单&#xff0c;需要运行一次再判断条件&#xff0c;所以通过do{}while(); 循环来实现多次。有多种选择&#xff0c;使用switch case选择语句&#xff0c;再在对应case…

蓝桥杯第229题 迷宫与陷阱 BFS C++ 模拟 带你理解迷宫的深奥

题目 迷宫与陷阱 - 蓝桥云课 (lanqiao.cn)https://www.lanqiao.cn/problems/229/learning/?page1&first_category_id1&name%E8%BF%B7%E5%AE%AB%E4%B8%8E%E9%99%B7%E9%98%B1 思路和解题方法 首先&#xff0c;定义了一个结构体node来表示迷宫中的每个节点&#xff0c;包…

计算机丢失vcomp140.dll是什么意思,如何解决与修复(附教程)

vcomp140.dll缺失的5种解决方法以及vcomp140.dll缺失原因 引言&#xff1a; 在日常使用电脑的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“vcomp140.dll缺失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了困扰。本文…

Java数据结构之优先级队列(PriorityQueue)

1、概念 队列&#xff1a;是一种FIFO&#xff08;First-In-First-Out&#xff09;先进先出的数据结构&#xff0c;对应于生活中的排队的场景&#xff0c; 排在前面的人总是先通过&#xff0c;依次进行。 优先队列&#xff1a;是特殊的队列&#xff0c;从“优先”一词&#xff…

免调试计量表,4G无线电表,可以远程抄表,安科瑞ADW300一款全能实现?

1.概述 ADW300 无线计量仪表主要用于计量低压网络的三相有功电能&#xff0c;具有体积小、精度高、功能丰富等优点&#xff0c;并 且可选通讯方式多&#xff0c;可支持 RS485 通讯和 Lora、NB、4G、wifi 等无线通讯方式&#xff0c;增加了外置互感器的电流采样 模式&#xff0…

计算机毕业设计 基于PHP的考研互助交流系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

设备管理的方法与思路

阅读本文你将了解设备管理的思路与方法&#xff1a;一、制定全面的管理计划&#xff1b;二、标准化管理流程&#xff1b;三、设备维护与保养&#xff1b;四、风险管理与预防&#xff1b;五、引入数字化工具。 设备管理在生产制造领域是保障生产安全和效率的核心环节。通过引入…

【c++|SDL】开始使用之---demo

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 SDL 记录 1. hello word #include<SDL2/SDL.h>SDL_Window* g_pWindow 0; SDL_Renderer* g_pRenderer 0;int main(int argc, char* args[]) {//…

DS八大排序之直接插入排序和希尔排序

前言 我们前面几期介绍了线性和非线性的基本数据结构。例如顺序表、链表、栈和队列、二叉树等~&#xff01;本期和接下来的几期我们来详解介绍各个排序的概念、实现以及性能分析&#xff01; 本期内容 排序的概念以及其运用 常见的排序算法 直接插入排序 希尔排序 一、排序的…

LeetCode(35)螺旋矩阵【矩阵】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 54. 螺旋矩阵 1.题目 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a…

甘草书店记: 2023年10月11日 星期三 晴 「做有光的人,照亮他人,也引人同行」

发了两篇《甘草书店记》&#xff0c;书店计划公之于众&#xff0c;收获了不少人的赞扬和鼓励&#xff0c;来自生活中的友人&#xff0c;来自麦田的客户和朋友&#xff0c;来自图书界的同行前辈&#xff0c;也来自商界的同仁。其中&#xff0c;最特别留言来自甘草书店投资方的张…

基于Tomcat+Eclipse+Mysql开发的图书信息管理系统

基于TomcatEclipseMysql开发的图书信息管理系统 项目介绍&#x1f481;&#x1f3fb; 环境要求&#xff1a; eclipse j2ee mysql5 jdk8 tomcat9 必须按上述环境要求运行项目&#xff0c;否则将无法运行&#xff01; 步骤&#xff1a; 1.打开eclipse导入项目 2.修改book-context…

MES系统的功能清单

MES系统的功能清单 一、生产计划管理 1. 订单和生产计划制定&#xff1a;根据客户需求和市场状况&#xff0c;制定生产计划和订单&#xff0c;确保生产资源的合理分配和生产进度的有效管理。 2. 生产排程&#xff1a;根据生产计划和订单&#xff0c;结合设备、人员、物料等资…

大一学编程怎么学?刚接触编程怎么学习,有没有中文编程开发语言工具?

大一学编程怎么学&#xff1f;刚接触编程怎么学习&#xff0c;有没有中文编程开发语言工具&#xff1f; 1、大一刚开始学编程&#xff0c;面对复杂的代码学习非常吃力&#xff0c;很难入门。建议刚接触编程可以先学习中文编程&#xff0c;了解其中的编程逻辑&#xff0c;学编程…

Shell - cron_protect.sh 监控 Python、Streaming 程序

目录 一.引言 二.Flink 程序监控 1.shell 脚本 2.crontab 配置 三.Python 程序监控 1.shell 脚本 2.crontab 配置 四.总结 一.引言 业务有流式处理数据的需求&#xff0c;需要 7x24 通过 Flink Python 程序进行处理。为了监控 Flink 与 Python 的程序运行状态并在程…

java List集合(ArrayList,LinkedList,Vector)

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍java List集合的三种实现类ArrayList&#xff0c;LinkedList&#xff0c;Vector以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习…

ZKP11.2 Fiat-Shamir and SNARGs

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 11: From Practice to Theory (Guest Lecturer: Alex Lombardi) 11.2 Fiat-Shamir and SNARGs Succinct Non-Interactive Arguments (SNARGs) This class so far: constructions of SNARGs using IOPs and a random oracle. …

【精选】SpringDI依赖注入及注解实现SpringIoC

SpringDI 什么是依赖注入 依赖注入&#xff08;Dependency Injection&#xff0c;简称DI&#xff09;&#xff0c;它是Spring控制反转思想的具体实现。 控制反转将对象的创建交给了Spring&#xff0c;但是对象中可能会依赖其他对象。比如service类中要有dao类的属性&#xff0…

什么是量子优势?

量子优势是量子计算领域正在积极努力的里程碑&#xff0c;量子计算机可以解决最强大的非量子或经典计算机无法解决的问题。 量子是指原子和分子的尺度&#xff0c;在这个尺度上&#xff0c;我们所经历的物理定律被打破&#xff0c;并且应用了一组不同的、违反直觉的定律。量子…