目录
前言
一、Hutool简介
二、后端操作
1、安装依赖
2、图形验证码接口
3、登录接口
三、前端操作
1、请求头与响应头的配置
2、验证码的显示
2.1 Blob格式是什么
2.2 URL.createObjectURL()方法
四、总结
前言
图形验证码在阻止恶意程序进行大量非法操作有着较为广泛的应用,同时,作为一种全自动的图灵测试,图形验证码确保只有人类才能完成指定任务,从而区分合法用户和机器模拟的请求。那么,如何在自己的项目中实现一个图形验证码呢?如何利用前后端的交互实现一个需要图形验证码的场景呢?下面,我将利用Hutool工具来实现登录过程中的图形验证码场景。最终效果如下图所示:
Hutool官方文档:https://loolly_admin.oschina.io/hutool-site/docs/#/
一、Hutool简介
Hutool是一个针对Java开发人员设计的小而全的Java工具类库,其目标是通过提供一系列静态方法封装常用API,以简化日常编程工作,降低开发者的学习成本,并显著提升开发效率。Hutool在设计上追求简洁、易用和高效,使得Java开发者可以更专注于业务逻辑的实现,而不是花费大量时间处理基础功能的编码。Hutool的主要特点包括:
- 静态方法封装:提供了大量的静态方法,方便直接调用,无需实例化对象。
- 广泛的功能覆盖:包含了日期时间处理、字符串操作、集合工具、文件操作、HTTP客户端、IO流操作、加密解密、数学计算、反射工具、线程与并发工具、验证码生成等多个模块,几乎涵盖了Java开发中常见的各种底层代码需求。
- 函数式语言般的优雅:通过精简的API接口设计,使得使用Hutool进行开发时可以像函数式语言那样便捷、流畅。
- 降低学习成本:整合了大量常用功能,减少了开发者对众多第三方库的学习负担,尤其是对于小型项目或解决小问题时,可以直接依赖Hutool完成任务。
验证码功能位于cn.hutool.captcha
包中,下面将介绍如何使用其提供的验证码功能。 后端采用的是Springboot,前端采用的是Vue2。
二、后端操作
1、安装依赖
在正式写代码之前,需要导入我们的Hutool工具。如果项目是采用Maven进行构建的,可以在pom.xml文件中添加以下几行配置信息:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
如果项目是利用Gradlle进行构建的,可以在其配置文件中添加如下信息,这里的版本可以根据自己的需求选择:
implementation 'cn.hutool:hutool-all:5.8.26'
博主的项目是基于Gradle构建的,以下是我的依赖配置情况:
2、图形验证码接口
将依赖导入进来后,便可以开始写我们的Java代码了,下面是一个在Controller层写的生成图形验证码的例子:
private final static String SESSION_KEY = "captcha"; // 验证码session key
//获取图形验证码
@GetMapping("/captcha")
public void generateCaptcha(HttpServletResponse response) throws Exception {
// 创建一个线型验证码实例
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(100, 40, 4,40); // 宽度、高度、字符和干扰线数量可自定义
// 设置验证码内容和输出到http响应
String code = captcha.getCode(); // 获取验证码文本内容
captcha.write(response.getOutputStream()); // 输出图片到浏览器
//将验证码内容存入响应头中
response.setHeader(SESSION_KEY, code);//这里的SESSION_KEY是我在前面自定义的一个常量字符串
}
在这里,我将验证码内容存入到了响应头中,目的是前端请求到验证码后,可以在响应体的响应头中拿到验证码对应的文本内容,将文本内容携带到下一次请求的请求头当中,后端再从请求头中拿到文本内容,与前端用户输入的验证码进行比较,以此判断用户输入的验证码是否正确。
下面,我们可以在浏览器输入相应的后端地址进行测试,如果能得到验证码,说明这一步成功了!
除了线型验证码实例,还有圆圈、扭曲等实例,大家可以参照官方文档。下面是CaptchaUtil这个工具类中的一些方法,大家在书写代码的时候可以跳到这个类中查看相应的注释信息,更好地理解方法的用途以及如何使用。
3、登录接口
接下来,需要实现用户登录接口,校验用户填写的验证码是否正确,以下是在Controller层写的一个登录接口示例:
/**
* 后台登录dto
*/
@Data
public class BackStageLoginDTO {
private String account; //账号
private String password; //密码
private String code; //验证码
}
@Autowired
LoginService loginService;
//管理后台登录接口
@PostMapping("/backstage/login")
public Result<BackstageLoginInfo> backstageLogin(@RequestBody BackStageLoginDTO json, HttpServletRequest request) throws Exception {
String captcha = request.getHeader(SESSION_KEY);//获取请求头中正确的验证码
String code = json.getCode();//用户输入的验证码
VerifyLegality.verifyStrIsEmpty(code, "请输入验证码!");//这个是我自己实现的用于校验一个字符串是否为空的方法。如果为空,则抛出“请输入验证码!”的异常。大家可以忽略这个。
//不区分大小写进行校验
if (!code.equalsIgnoreCase(captcha)) {
throw new Exception("验证码错误");
}
BackstageLoginInfo data = loginService.backstageLogin(json);//调用登录逻辑
return Result.success(data);
}
在这里,我们从请求头中获取正确的验证码信息,然后与用户输入的验证码进行校验;校验通过则执行接下来的登录逻辑,否则不进行登录。
三、前端操作
1、请求头与响应头的配置
在创建的axios实例中添加相应的配置信息,配置获取验证码或者携带验证码的信息。
2、验证码的显示
首先,写出前端的请求方法,需要返还的数据形式,具体如下图所示:
接下来,在相应的登录界面导入这个请求方法,将请求到的二进制数据转换成临时的url进行渲染即可,具体如下图所示:
2.1 Blob格式是什么
Blob(Binary Large Object)是一种数据格式,它代表不可变的原始二进制数据。在JavaScript和许多数据库系统中,Blob对象用于存储和处理任意类型的二进制数据,包括但不限于图像、音频、视频和其他非文本文件内容。在JavaScript环境中,Blob对象是一个内置的数据类型,可以用来表示一个无法直接读取或修改内部结构的二进制数据块。你可以创建Blob对象来封装从网络请求得到的数据流、用户上传的文件内容、或者由字符串、ArrayBuffer等转换而来的内容。
Blob对象的核心特征:
- 不可变性:一旦创建,就不能更改其内容。
- 多用途:可用于任何类型的二进制数据,如图片、音频、视频或其他自定义二进制格式。
- MIME类型标识:可以通过type属性指定Blob对象所包含数据的MIME类型,帮助浏览器或其他处理程序理解数据的格式。
- 构造方式灵活:可以通过构造函数接收一个数组参数,该数组可以是ArrayBuffer、ArrayBufferView、Blob、DOMString等对象,以及一个描述这些数据的配置对象(如MIME类型)。
例如,在JavaScript中创建一个简单的文本Blob对象:
var text = "Hello, World!";
var blob = new Blob([text], { type: "text/plain;charset=utf-8" });
这个Blob对象现在就包含了“Hello, World!”文本,并且指定了MIME类型为"text/plain",这样当通过URL.createObjectURL()方法将其转化为一个URL时,浏览器会知道这是一个纯文本文件。
2.2 URL.createObjectURL()方法
URL.createObjectURL()
是一个 JavaScript Web API 方法,它允许开发者基于给定的对象(通常是 Blob
或 File
类型)创建一个指向该对象的 URL。这个方法由全局构造函数 URL
的静态方法提供,返回一个 DOMString 类型的值,这个值代表了一个唯一的、临时的 URL,可以直接用在 <img>
、<video>
、<audio>
等标签的 src
属性上,或者通过 XMLHttpRequest 上传到服务器。
使用场景:
- 图片预览:用户选择文件后,可以通过此方法生成一个可以立即显示在页面上的图片预览链接。
- 文件操作:无需将大文件完整加载到内存中,就可以进行下载、预览或其他操作。
基本语法:
var blob = new Blob( /* content */, {type: "mime-type"});
var objectURL = URL.createObjectURL(blob);
当调用 URL.createObjectURL(blob)
时,浏览器会在内部为指定的 Blob 对象创建一个指向其内容的本地URL,这个URL是不可跨域访问的,并且只在当前文档上下文中有效,也就是说,当文档卸载或执行 URL.revokeObjectURL()
来释放资源时,这个URL就不再可用。
重要提示:
- 创建的URL是暂时性的,为了防止内存泄漏,不再需要使用该URL时,应调用
URL.revokeObjectURL(objectURL)
来释放与之关联的内存资源。 - 这个方法对于处理用户选择的文件尤其有用,例如从
<input type="file">
控件中选择的图片或文档。
总结起来,URL.createObjectURL()
是一种方便的方式,用于在不直接读取或转移二进制数据的情况下,通过URL引用和操作这些数据。
四、总结
路漫漫其修远兮,吾将上下而求索。 文章篇幅较长,感谢您能看到这里,博主水平有限,难免存在有不足的地方,欢迎各位大佬指出。让我们一起朝更好的方向努力前进吧!