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

一、实现效果

在这里插入图片描述

二、步骤

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

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;@Overridepublic 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));}@Overridepublic boolean isManifestParsingEnabled() {return false;}/*** Cookie管理类*/private class CookiesManager implements CookieJar {//保存每个url的cookieprivate HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();//上一个请求urlprivate HttpUrl url;@Overridepublic void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {//保存链接的cookiecookieStore.put(httpUrl, list);//保存上一次的url,供给下一次cookie的提取。url = httpUrl;}@Overridepublic List<Cookie> loadForRequest(HttpUrl httpUrl) {//加载上一个链接的cookieList<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;}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setStyle(STYLE_NORMAL, R.style.CustomDialog);setCancelable(false);}@Nullable@Overridepublic 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() {@Overridepublic void onClick(View v) {//加载图形验证码loadCapture();}});loadCapture();final EditText etCode = view.findViewById(R.id.et_code);ivDelete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//关闭图形验证码弹窗dismiss();}});Button ivSure = view.findViewById(R.id.iv_login);ivSure.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (TextUtils.isEmpty(etCode.getText().toString())) {RnToast.showToast(getContext(),"请输入图形验证码");return;}//图形验证码输入完成后,发送短信验证码请求new Thread(new Runnable() {@Overridepublic 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() {@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {Log.d("mylog_sms: ","短信验证码接口请求失败"+e.toString());}@Overridepublic 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.ConstraintLayoutandroid:layout_width="300dp"android:layout_height="wrap_content"android:layout_gravity="center"android:background="@drawable/shape_white_8"><ImageViewandroid: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" /><TextViewandroid: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" /><ImageViewandroid: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" /><EditTextandroid: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" /><Buttonandroid: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() {@Overridepublic void onGetCode() {//短信验证码接口请求成功countdown();}@Overridepublic void onGetCodeFailed(String msg) {runOnUiThread(new Runnable() {@Overridepublic 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>() {@Overridepublic Long apply(Long aLong) throws Exception {return count - aLong;}}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Long>() {@Overridepublic void onSubscribe(Disposable d) {
//                        addSubscribe(d);}@SuppressLint("SetTextI18n")@Overridepublic void onNext(Long aLong) {mTvGetCode.setText(aLong + "s");mTvGetCode.setEnabled(false);}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {mTvGetCode.setText(getString(R.string.change_phone9));mTvGetCode.setEnabled(true);}});}

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

四、完成,Nice!

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

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

相关文章

做项目,要从学生思维里跳出来

今天分享下在23期群的聊天记录&#xff0c;关于做项目正确的思维&#xff0c;自己曾经走过一些弯路&#xff0c;希望大家能Get到。 做项目&#xff0c;一定要从学生思维里跳出来。 1.学生思维就是前期就想每个细节都要搞懂&#xff0c;感觉才能往下&#xff0c;其实像lora&…

我的CSDN创作纪念日

⭐前言 同志们&#xff0c;大家好&#xff01;我是乱码怪才&#xff0c;这篇博客我来分享一下我和CSDN的故事————一个人工智能学生和CSDN的相遇。 &#x1f496;相遇CSDN&#x1f496; 我在刚上大学的时候就下载了CSDN&#xff0c;那时候只是在平台上搜一些C语言的算法题…

基于可穿戴的健康监护终端--研究进展报告

基于可穿戴的健康监护终端--研究进展报告 1 引言2 传感器介绍2.1 呼吸速率传感器2.2 温度传感器2.3 心脏跳动传感器 3 论文介绍3.1 Effective Data Decision-Making and Transmission System Based on Mobile Health for Chronic Disease Management in the Elderly3.2 Design …

代码随想录算法训练营 ---第四十六天

第一题&#xff1a; 简介&#xff1a; 本题的重点在于确定背包容量和物品数量 确定dp数组以及下标的含义 dp[i] : 字符串长度为i的话&#xff0c;dp[i]为true&#xff0c;表示可以拆分为一个或多个在字典中出现的单词。 2.确定递推公式 如果确定dp[j] 是true&#xff0c;且…

C语言结构体数组实现一个简单的登录注册功能

实现登录注册 登录功能&#xff1a;设计了一个结构体数组用来记录系统中所存在的人。首先设置了一个管理员身份的存放在第一行。登录的时候首先判断账号是否存在于数组当中。进行遍历数组中的所有元素的操作来进行查询&#xff0c;若是可以查询到那么就可以来判断他的密码是否…

AI Agent应用落地前半场,属于企服软件厂商推出的平台级AI智能体

GPTs大受欢迎但问题多&#xff0c;企服厂商的AI Agent更被B端客户器重 比尔盖茨预言智能体是下个平台&#xff0c;超自动化平台的AI Agent更靠谱&#xff1f; 以GPTs为代表的AI Agent只是玩具&#xff1f;揭秘真实可用AI智能体长什么样 AI Agent应用落地前半场&#xff0c;属…

力扣hot100 最大子数组和 动态规划 分治 无后效性 子问题划分

&#x1f468;‍&#x1f3eb; 题目地址 无后效性 为了保证计算子问题能够按照顺序、不重复地进行&#xff0c;动态规划要求已经求解的子问题不受后续阶段的影响。这个条件也被叫做「无后效性」。换言之&#xff0c;动态规划对状态空间的遍历构成一张有向无环图&#xff0c;遍…

SRGAN 使用指南:将低分辨率图像转换为高分辨率图像

SRGAN、ESRGAN、Real-ESRGAN 使用指南 SRGAN网络结构优化目标 ESRGANReal-ESRGAN SRGAN 超分辨率&#xff1a;从低分辨率(LR)图像来估计其对应高分辨率(HR)图像的任务&#xff0c;被称作超分辨率(SR)。 SRGAN 图像超分辨率的深度学习模型&#xff0c;通过生成对抗网络&#x…

LeetCode(33)最小覆盖子串【滑动窗口】【困难】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 76. 最小覆盖子串 1.题目 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a; 对于 t 中重复字…

Vim多行编辑

Vim多行编辑 Ctrlq进入多行编辑模式&#xff0c;然后上下选择要编辑的行 按下I或者Shifti&#xff0c;进入编辑模式 编辑的时候多行不会同时变化&#xff0c;不要担心&#xff0c;确实是多行编辑 编辑完成&#xff0c;想要结束多行编辑&#xff0c;按下Esc&#xff0c;此时…

视频水印怎么去除?3种方法让你轻松去除视频水印

剪辑作为当下自媒体必备技能&#xff0c;通过视频二次剪辑创作出吸引眼球的视频内容&#xff0c;然而&#xff0c;网上下载保存的图片/视频素材往往下载后会带有水印&#xff0c;于是去除水印便成为了不少人的头疼之事&#xff01; 为了解决这个问题&#xff0c;我们可以尝试以…

vue select选择下拉组织树,解决不出现横向滚动条

背景&#xff1a;由于项目需求需要使用下拉选择框的组织架构树 实现代码如下&#xff1a; <el-row><el-col :span"18"><el-form-item label"所属组织:" prop"groupName"><el-select v-model"dataForm.groupName"…

国内某知名半导体公司:实现虚拟化环境下的文件跨网安全交换

立足特定应用领域的创新型企业 上海某半导体公司是中国10大集成电路设计公司之一的子公司。该半导体公司是一家特色工艺集成电路芯片制造企业&#xff0c;专注模拟电路、功率器件所需的特色生产工艺研发与制造&#xff0c;。 该半导体公司不断追求创新&#xff0c;提高自身产…

python爱心代码高级

在Python中&#xff0c;我们可以使用matplotlib库来创建一个更高级的爱心图形。以下是一个示例&#xff1a; import matplotlib.pyplot as pltimport numpy as npx np.linspace(-2, 2, 1000)y1 np.sqrt(1-(abs(x)-1)**2)y2 -3*np.sqrt(1-(abs(x)/2)**0.5)fig, ax plt.subp…

【Java Spring】SpringBoot 日志系统

文章目录 一、Spring Boot 日志系统1.1 Spring Boot 日志框架1.2 自定义日志打印1.3 日志级别设置1.4 日志持久化1.5 lombok 简化日志输出 一、Spring Boot 日志系统 1.1 Spring Boot 日志框架 SLF4J 和 logback都是spring boot内置的日志框架&#xff0c;开发者只负责调用对…

Java HashMap

HashMap 是 Map 接口中基于哈希表的非同步实现, 自身也可以自动扩容。使用时可以通过 key 快速定位到对应的 value。key 和 value 同时可以都为 null。 1 HashMap 的结构定义 JDK1.8 对 HashMap 进行了比较大的优化, 底层实现由之前的 “数组 链表” 改为 “数组 链表 红黑…

Selenium 学习(0.15)——软件测试之测试用例设计方法——场景法

1、场景法的基本概念 场景法是黑盒测试中一种重要的测试用例设计方法。它通过场景描述业务流程&#xff0c;包括基本流和备选流设计测试用例遍历软件系统功能&#xff0c;从而验证其正确性。 通过运用场景对系统的功能点或业务流程进行描述&#xff0c;从而提…

Maven Helper插件——实现一键Maven依赖冲突问题

总结/朱季谦 业余在一个SpringBoot项目集成Swagger2时&#xff0c;启动过程一直出现以下报错信息—— An attempt was made to call a method that does not exist. The attempt was made from the following location: ​ springfox.documentation.schema.DefaultModelDepe…

独立搭建UI自动化测试框架分享

前言 今天给大家分享一个seleniumtestngmavenant的UI自动化&#xff0c;可以用于功能测试&#xff0c;也可按复杂的业务流程编写测试用例&#xff0c;今天此篇文章不过多讲解如何实现CI/CD&#xff0c;只讲解自己能独立搭建UI框架&#xff0c;如果有其他好的框架也可以联系我&…