JavaWeb 实现验证码功能(demo)
发布时间 - 2026-01-10 22:56:43 点击率:次验证码不用多说,在 WEB-APP 中一般应用于:登录、注册、买某票、秒杀等场景。大家都接触过~可以说是千奇百怪,各式各样。

DEMO 目标功能
- 验证码页面输入。
- 页面更换验证码(异步实现)。
- 后台验证并返回验证结果。
开工
页面:demo1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>验证示例</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<style type="text/css">
img {
width: 87px;
height: 33px;
border: 1px solid gray;
}
#msg {color: red;} /* 后台返回的验证信息显示为红色 */
</style>
</head>
<body>
<form action="${pageContext.request.contextPath}/check" method="post" enctype="application/x-www-form-urlencoded">
验证码:<input type="text" name="code" size="4" maxlength="4" id="code" />
<img id="code-img" src="" alt="验证码" style="display: none;"/>
<a href="javascript:void(0)" rel="external nofollow" id="changeCode">看不清?换一张</a> <br/><br/>
<input type="submit" value="验证"/> <span id="msg">${msg}</span>
</form>
</body>
</html>
说明:
"看不清?换一张" 的 href 属性写成 javascript:void(0) 是为了防止页面刷新,这里的更换功能交给 AJAX 异步完成。
JavaScript 工具:util.js(为啥用原生 JS?任性呗~哈)
/**
* 获取 XMLHttpRequest Object
* @returns XMLHttpRequest Object
*/
function getXHR() {
var xmlHttp;
try { // Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) { // Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Sorry, 您的浏览器不支持 AJAX!");
return false;
}
}
}
return xmlHttp;
}
页面中的 JavaScript 代码
<script type="text/javascript" src="${pageContext.request.contextPath}/js/util.js"></script>
<script type="text/javascript">
var xhr = getXHR(); // 获得 XMLHttpRequest 对象
// 页面加载时加载验证码,但验证码初始为隐藏状态
window.onload=function() {
// 为 onreadystatechange 事件注册回调函数。由于 xhr 为全局变量,所以注册后就不用管啦
xhr.onreadystatechange=function() {
if(xhr.readyState==4 && xhr.status==200) {
document.getElementById('code-img').src="data:image/png;base64,"+xhr.responseText;
}
}
xhr.open("GET","${pageContext.request.contextPath}/captcha/code",true);
xhr.send(null);
}
// 验证码输入框获得焦点时,验证码状态更改为显示
document.getElementById('code').onfocus=function() {
document.getElementById('code-img').style.display="inline";
}
// 异步请求,更换验证码
document.getElementById('changeCode').onclick=function() {
xhr.open("GET","${pageContext.request.contextPath}/captcha/code",true);
xhr.send(null);
}
</script>
生成验证码的 CaptchaCodeServlet.java
package com.leo.web.captcha;
import java.io.IOException;
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 com.leo.util.ImageUtil;
import cn.dsna.util.images.ValidateCode;
@WebServlet("/captcha/code")
public class CaptchaCodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// 生成验证码(构造参数分别代表:宽度,高度,字符数,干扰线条数)
ValidateCode code = new ValidateCode(87, 33, 4, 23);
// 将验证码保存到 session 中,用于验证
request.getSession().setAttribute("code", code.getCode());
// 响应返回验证码图片 base64 编码后的数据给浏览器
response.getWriter().write(ImageUtil.encodeImg2Base64(code.getBuffImg(), "png"));
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
this.doGet(request, response);
}
}
说明:
这里使用了 Servlet3.0 的新特性-用注解配置 url-pattern(用起来挺爽的),也就是说简单的项目不再需要 web.xml 了,但是 Tomcat 需要 7.0+。
其次生成验证码我用了一个小工具:ValidateCode.jar。工具十分简单,不合心意完全可以自己写。但也就是因为功能太少,所以我又写了一个 ImageUtil。我也有打算自己开源一个验证码工具出来。
ImageUtil.java
package com.leo.util;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import sun.misc.BASE64Encoder;
public class ImageUtil {
/**
* 将图片二进制数据进行 base64 编码
* @param bufImg
* @return base64 编码后的字符串
*/
public static String encodeImg2Base64(BufferedImage bufImg, String formatName) {
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
ImageIO.write(bufImg, formatName, outputStream);
} catch (IOException e) {
throw new RuntimeException("Base64 编码失败!"+e.getMessage());
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(outputStream.toByteArray());
}
private ImageUtil() {} // 工具类私有化构造方法是常见的做法
}
说明:
为什么要把图片二进制数据进行 Base64编码 呢?因为<img/>标签虽然可以直接设置 src 属性值为${pageContext.request.contextPath}/captcha/code请求相应的 Servlet 来得到二进制数据直接显示,但在 AJAX 异步请求中响应返回的是 xhr.responseText 。当把数据直接给 img 标签的 src 属性时,用 Chrome-tool 查看只会是一堆二进制当作文本解析的乱码字符,所以才要多这一步。
或许我作为萌新不知道一些其它的方便技巧。但若不想使用异步,那直接 img src 设置为请求地址将是最简单的选择,更换验证码无非是监听事件 img src 重新设置为该地址(再来一次请求)。
详细的资料:JS在浏览器中解析Base64编码图像
Base64图片编码解析及浏览器的兼容性处理
后台验证验证码:CheckServlet.jave
package com.leo.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/check")
public class CheckServlet extends HttpServlet {
private static final long serialVersionUID = -6588625852621588221L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String encoding = "UTF-8";
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
/* 验证码验证 */
String inputCode = request.getParameter("code");
// 获得 session 中的正确验证码
String realCode = (String) request.getSession().getAttribute("code");
System.out.println("input: "+inputCode+"\nreal: "+realCode); // 用于 Debug
if(!(inputCode!=null && realCode!=null &&
inputCode.equalsIgnoreCase(realCode))) {
// 若验证码不正确:回到页面并提示错误
request.setAttribute("msg", "验证码错误!请重新输入");
request.getRequestDispatcher("/demo1.jsp").forward(request, response);
return;
}
// 验证码正确,响应一句话表示 OK
response.getWriter().write("验证成功!");
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}
}
说明:
doGet() 方法一开始是对中文乱码进行处理,编码统一设为 UTF-8。在实际项目中,编码问题通常交给一个 Filter 完成,达到一劳永逸的效果。
效果
警告!警告!!颜控请速速撤离!!!
写在最后
以上就是 JavaWeb 验证码小 DEMO 的全部内容啦,最好是把验证提交也搞成异步的,这里就不整了。WEB 项目中还没尝试过添加验证码功能的小伙伴可以动手搞起来啦!实际项目中利用 JQuery 等框架处理 AJAX,再配上一个漂亮的前端页面就完美啦。
以上所述是小编给大家介绍的JavaWeb 实现验证码功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# javaweb
# 验证码
# 三分钟带你掌握Java开发图片验证码功能方法
# Java实现滑块拼图验证码
# java生成图片验证码返回base64图片信息方式
# 二进制数
# 小编
# 的是
# 您的
# 加载
# 也有
# 还没
# 大家都
# 在此
# 设为
# 但在
# 我又
# 要把
# 只会
# 用了
# 将是
# 给大家
# 但也
# 可以直接
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Python自动化办公教程_ExcelWordPDF批量处理案例
Python文本处理实践_日志清洗解析【指导】
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
Laravel如何自定义分页视图?(Pagination示例)
百度浏览器如何管理插件 百度浏览器插件管理方法
JS弹性运动实现方法分析
lovemo网页版地址 lovemo官网手机登录
桂林网站制作公司有哪些,桂林马拉松怎么报名?
Laravel中的Facade(门面)到底是什么原理
高防服务器租用如何选择配置与防御等级?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
网站建设整体流程解析,建站其实很容易!
如何用景安虚拟主机手机版绑定域名建站?
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
网站建设要注意的标准 促进网站用户好感度!
Android仿QQ列表左滑删除操作
如何在万网主机上快速搭建网站?
移动端脚本框架Hammer.js
香港网站服务器数量如何影响SEO优化效果?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
Laravel如何处理和验证JSON类型的数据库字段
Laravel中的withCount方法怎么高效统计关联模型数量
Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
Swift中循环语句中的转移语句 break 和 continue
实例解析Array和String方法
如何获取上海专业网站定制建站电话?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能
Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】
Android Socket接口实现即时通讯实例代码
使用C语言编写圣诞表白程序
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
重庆市网站制作公司,重庆招聘网站哪个好?
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
JS经典正则表达式笔试题汇总
Laravel如何保护应用免受CSRF攻击?(原理和示例)
详解jQuery中基本的动画方法
佛山企业网站制作公司有哪些,沟通100网上服务官网?
Bootstrap CSS布局之列表
Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程
Laravel如何实现数据库事务?(DB Facade示例)
Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析
香港服务器网站生成指南:免费资源整合与高速稳定配置方案
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
如何在IIS中新建站点并配置端口与物理路径?

