验证码功能的简单实现(完整代码+详解) |
您所在的位置:网站首页 › 这个电话不能用作验证用途的英文 › 验证码功能的简单实现(完整代码+详解) |
介绍
验证码,作为一种基本的安全措施,帮助在用户验证过程中防止自动化滥用。在这篇博客中,我将分享如何在 Java Web 应用程序中从头开始实现一个简单但有效的验证码功能 效果图如下: 注:本文仅介绍验证码功能的原理和简单实现,大家应根据具体应用场景和需求对代码做出修改和完善 环境与技术栈 环境和技术栈 开发环境:IntelliJ IDEA后端技术:Java, Servlet前端技术:HTML, JavaScript工具类:CaptchaUtils.java 实现步骤: 生成验证码图像:使用 Java 的图形和文本 API,如 java.awt 包中的类,来生成包含随机字符的图像。可以使用 BufferedImage 类创建图像,并用 Graphics2D 类来绘制随机生成的字符和干扰线等。存储验证码信息:生成的验证码需要在服务器端进行存储,以便验证用户输入的验证码是否正确。这通常通过会话(Session)来实现。提供刷新功能:允许用户通过点击“换一换”来获取新的验证码。这通常涉及到一个 JavaScript 函数,它会发起一个请求到服务器以获取新的验证码图像。前端展示:在用户界面上显示验证码图像,并提供一个输入框供用户输入验证码。同时,提供一个“换一换”链接,用户点击连接或者验证码图像可以刷新验证码。验证用户输入:当用户提交表单时,后端将检查用户输入的验证码与会话中存储的验证码是否匹配。 步骤实现与解析: 一.创建验证码工具类在 Java Web 应用程序中实现验证码功能的核心在于 CaptchaUtils 工具类。这个类负责生成验证码图片并输出到客户端。以下是这个类的关键功能以及它们如何协同工作: 生成随机字符串 :生成随机字符串作为验证码的文本。首先定义一个包含所有可能字符(大写字母、小写字母、数字)的字符串,然后使用 Java 的 Random 类来随机选择其中的字符来构建一个指定长度的验证码字符串。创建图像:创建一个包含验证码文本的图像。使用 BufferedImage 类来创建空白图像,最后利用 Graphics2D 对象在图像上绘制生成的随机字符串。可以设置字体、大小和颜色以增强视觉效果和安全性。增加噪点和干扰线:通过添加噪点和干扰线使自动识别变得更困难。在图像上随机绘制小点和线条。这些干扰元素增加了验证码破解的难度,同时对人类用户的识别影响较小。输出图像:将生成的验证码图像输出到客户端。使用 ImageIO.write 方法将 BufferedImage 输出到 HttpServletResponse 的输出流中。完整代码如下: package zua.util; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; public class CaptchaUtils { //定义验证码图像属性 private static final int WIDTH = 80;//图像宽度 private static final int HEIGHT = 40;//图像高度 private static final int LENGTH = 4;//验证码字符数量 private static final Random random = new Random();// 用于生成随机数,便于设置rgb参数 /** * 创建验证码图像并返回验证码上的文本 * * @param response HttpServletResponse, 用于输出图像到客户端 * @return 返回生成的验证码文本 */ public static String createCaptchaImage(HttpServletResponse response) { // 创建BufferedImage对象,这是一个包含图像数据的缓冲区 BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); // 获取Graphics2D对象,可以在图像上进行绘制 Graphics2D g = image.createGraphics(); // 设置背景色为白色并填充整个图像区域 g.setColor(Color.WHITE); g.fillRect(0, 0, WIDTH, HEIGHT); // 设置字体,使用Arial字体,加粗,大小20 g.setFont(new Font("Arial", Font.BOLD, 20)); // 随机生成验证码文本字符 String captchaText = generateRandomText(LENGTH); int x = 10; // 横坐标开始位置 // 逐个绘制验证码中的字符 for (char c : captchaText.toCharArray()) { // 随机生成字符颜色(rgb) g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255))); // 绘制字符,并随机调整字符的垂直位置 g.drawString(String.valueOf(c), x, 20 + random.nextInt(20)); x += 20;// 将横坐标移动到下一个字符的绘制位置 } // 添加噪点,使图像中的验证码不易被自动识别 g.setColor(Color.LIGHT_GRAY); for (int i = 0; i < 20; i++) { int x1 = random.nextInt(WIDTH); int y1 = random.nextInt(HEIGHT); int x2 = random.nextInt(12); int y2 = random.nextInt(12); g.drawLine(x1, y1, x1 + x2, y1 + y2);// 绘制一条小线段,代表噪点 } // 完成图像的绘制,释放图形上下文使用的系统资源 g.dispose(); // 设置响应内容类型为JPEG图像 response.setContentType("image/jpeg"); try { // 将创建的图像写入响应的输出流中 ImageIO.write(image, "JPEG", response.getOutputStream()); // 刷新输出流,确保图像数据完整发送 response.getOutputStream().flush(); } catch (IOException e) { e.printStackTrace(); } // 返回生成的验证码文本 return captchaText; } /** * 生成随机文本,用于验证码 * * @param length 需要生成的文本长度 * @return 返回生成的随机文本 */ private static String generateRandomText(int length) { // 定义可能出现在验证码中的字符 String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; // 随机选择字符并添加到StringBuilder中 StringBuilder sb = new StringBuilder(length); for (int i = 0; i < length; i++) { // 将StringBuilder转换为字符串并返回 sb.append(chars.charAt(random.nextInt(chars.length()))); } return sb.toString(); } } 二.Servlet处理接下来,我们创建 CaptchaServlet 类来处理生成验证码的请求。在 doGet 方法中,我们调用 CaptchaUtils 来生成图像并将验证码文本保存在 session 中。在 doPost 方法中,我们比较用户输入的验证码和 session 中设定的的验证码。 代码如下: package zua.servlet; import com.google.gson.Gson; import zua.util.CaptchaUtils; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.Console; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/captcha") public class CaptchaServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 创建验证码图片并返回图片上的文本 String captchaText = CaptchaUtils.createCaptchaImage(response); // 将验证码文本保存到Session中 HttpSession session = request.getSession(); session.setAttribute("captcha", captchaText); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取用户输入的验证码 String userInputCaptcha = request.getParameter("captcha"); // 从Session中获取真正的验证码 HttpSession session = request.getSession(); String realCaptcha = (String) session.getAttribute("captcha"); // 比较用户输入的验证码和真正的验证码是否一致 // 设置响应类型为JSON response.setContentType("application/json"); PrintWriter out = response.getWriter(); Gson gson=new Gson();//gson需要相应jar包,如没有下面选其一种方式即可: /* * maven: * com.google.code.gson gson 2.10.1 * * jar下载路径: * https://mvnrepository.com/artifact/com.google.code.gson/gson/2.10.1 * */ String json; if (userInputCaptcha != null && userInputCaptcha.equalsIgnoreCase(realCaptcha)) { json=gson.toJson("success"); } else { json=gson.toJson("fail"); } out.write(json); } }注意:示例中用的gson格式数据,需要下载jar包或在pow里添加依赖,代码中已给出下载地址和maven依赖,根据需求选用其一即可 三.客户端实现在 HTML 页面中,我们使用一个 img 标签来显示验证码图像,并提供一个刷新链接。JavaScript 用于处理验证码的刷新和表单提交。 代码如下: Captcha Example1.在HTML中放置一个 2.服务器生成图像: 当请求到达服务器,并被映射到你的CaptchaServlet时,doGet方法会被调用。在doGet方法中,CaptchaUtils.createCaptchaImage(response);会负责生成一个图像,并将其写入到响应的输出流中。 3.响应与图像数据: 服务器响应请求并将图像数据作为响应体发送回客户端。此时,响应的MIME类型应该被设置为图像的MIME类型(如image/png)。 4.浏览器接收并渲染图像: 浏览器接收到包含图像数据的响应后,就会在 5.刷新验证码: 当用户点击“换一换”时,refreshCaptcha函数会被调用。这个函数会通过更改 所以,客户端接收图像的关键在于 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |