使用jcaptcha在Struts中生成验证码

部署运行你感兴趣的模型镜像
jcaptcha, 是一个Java开源项目, 为Java Completely Automated Public Test to tell Computers and Humans Apart 的简写, 字面意思就是Java实现的可以区分计算机和人的测试.
具体的测试方法有很多种, 比如:
验证码 - (这里讨论的)
音频 - (比如朗读几个字母, 用户输入这些字母来验证)

JCAPTCHA在Struts中配置很简单, 主要是以下三个部分:

1. 需要一个Action或者Servlet来作为页面的接口. 在访问该Acton或Servlet的时候, 调用(2) 生成随机的验证对象, 和当前的Session关联起来;
2. 一个JCAPTCHA Service类. 这个类完成读取配置(如何生成验证码, 生成的内容是什么, 等等), 并实际生成验证码. 同时也对外提供验证用户输入的功能.
3. 其它部分. 比如在UI层需要调用(1)来显示验证码图片, 在验证部分要调用(2)来测试输入的验证码是否正确.

下面是代码.

struts-config.xml:

<action path="/jcaptcha" type="test.CaptchaAction" />

与之对应的JSP部分. 很简单, 一个验证码图片, 一个输入框, 一个提交按钮.

<body>
<img src="<%= request.getContextPath() %>/jcaptcha.do"/>
<form method="POST" action="<%= request.getContextPath() %>/test.do?state=verify">
<input name="code"/>
<input type="submit"/>
</form>
</body>

加入一个Action, 作用就是生成图片(写成一个Servlet也能完成一样的功能). Java代码为:

public class CaptchaAction extends Action {


public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

try {

CaptchaService.getInstance().writeCaptcha(request, response);

} catch (Exception e) {

e.printStackTrace();

return mapping.findForward("fatal");

}

return super.execute(mapping, form, request, response);

}

}


下面的就是重要的单例类CaptchaService了. 这个类继承自ListImageCaptchaEngine, 是JCAPTCAH的针对图片验证的类. CaptchaService类中有三个方法比较重要:

1. private buildInitialFactories()

这个方法是ListImageCaptchaEngine的abstract方法的覆盖. 必须实现. 目的是初始化验证码生成器的参数.


protected void buildInitialFactories() {

try {

SimpleTextPaster parser = (new SimpleTextPaster(MIN_LENGTH, MAX_LENGTH, Color.black));

//RandomTextPaster parser = new RandomTextPaster(MIN_LENGTH, MAX_LENGTH, Color.black);



//UniColorBackgroundGenerator back = new UniColorBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT);

GradientBackgroundGenerator back = (new GradientBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT, Color.orange, Color.white));


Font f = Font.decode("Consolas");

RandomFontGenerator rf = (new RandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE, new Font[]{f}));// to easy to read


WordGenerator words = new RandomWordGenerator("ABCDEFG");



WordToImage word2image = new ComposedWordToImage(rf, back, parser);

ImageCaptchaFactory factory = new GimpyFactory(words, word2image);

addFactory(factory);

} catch (Exception ex) {

ex.printStackTrace();

}

}


对上面程序的解释. 一个验证码图片由四部分组成: TestParser, BackgroundGenerator, FontGenerator, 以及WordGenerator


TestParser, 都是从类AbstractTextPaster继承来, 作用是生成验证码中的文字部分. 较常用的下面两种:

- SimpleTextPaster 简单的实现. 文字部分是从左到右顺序排列的. 构造函数的参数分别为最短长度, 最大长度和文字颜色.
- RandomTextPaster 带有随机式样的实现. 和SimpleTextPaster的参数类似. 不过生成的文字部分, 带有随机的样式(粗体,斜体等), 开始位置也是随机的(可能从图片中间开始排列)


BackgroundGenerator, 都是从AbstractBackgroundGenerator类继承而来. 作用是产生验证码图片的背景. 构造的时候传入的基本参数为图片的宽度和高度. 常用的实现为:

- UniColorBackgroundGenerator 单一背景色. 默认的是白色.

- GradientBackgroundGenerator 渐变背景色. 在构造的时候需要指定起始颜色和终止颜色.


FontGenerator, 从AbstractFontGenerator 继承来. 但是和上面两种不同, 基本上在应用中使用的都是RandomFontGenerator. 构造的时候, 传入字体的最小值, 最大值, 以及字体列表的名称. 在生成验证码的时候, 随机选择某种字体, 某种大小来生成. 这里有几个问题需要注意:


FontGenerator字体的大小, TestParser中验证码的个数, 以及BackgroundGenerator中图片的大小需要匹配. 如果设置的不合理, 比如字体过大, 生成若干个验证码后发现图片的大小太小装不下了, 将出现异常.


在选择字体的时候, 下面两种名称开头字体是JCAPTCHA禁止使用的: Courier 和 Times Roman . 因为这两种字体用的太广泛了, 同时也是比较标准的字体, JCAPTCHA认为它们不够安全(容易被识别程序识别出来), 所以将忽略这些字体. 如果没有设置其他的字体的话, 会报错(找不到可用的字体).


WordGenerator: 生成文字的选项. 基本上用的都是RandomWordGenerator随机生成. 构造参数为可选的列表. 生成验证码的时候, 将从这些文字中选择.


这四项确定以后, 就可以生成一个factory, 加入生成列表里面去:


WordToImage word2image = new ComposedWordToImage(rf, back, parser);

ImageCaptchaFactory factory = new GimpyFactory(words, word2image);

addFactory(factory);


同样的, 可以有多个TestParser, BackgroundGenerator, FontGenerator, 生成多个factory, 这样每次生成验证码图片的时候都会更加不同.


2. writeCaptcha方法. 该方法的作用就是实际将图片写入response, 最终显示到浏览器上.

没什么特殊的. 唯一一点是, 通过setAttribute方法在当前的session中保存了验证码.


public void writeCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
//保存验证码
imageCaptcha = getNextImageCaptcha();
HttpSession session = request.getSession();
session.setAttribute(KEY, imageCaptcha);
BufferedImage image = (BufferedImage) imageCaptcha.getChallenge();

OutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outputStream);
encoder.encode(image);

outputStream.flush();
} catch (IOException ex) {
throw ex;
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException ex) {
}
}
imageCaptcha.disposeChallenge();
}
}


3. 验证方法. 验证用户输入的验证码是否正确.
很简单的一个方法.

public boolean validateCaptcha(String validateCode, HttpSession session) {
try {
if (session == null) {
return false;
}
imageCaptcha = (ImageCaptcha) session.getAttribute(KEY);
if (imageCaptcha == null) {
return false;
}
validateCode = validateCode.toUpperCase();
boolean flag = (imageCaptcha.validateResponse(validateCode)).booleanValue();
session.removeAttribute(KEY);
return flag;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}


剩下的 Action 部分, 加入判断:


public ActionForward verify(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String code = request.getParameter("code");
boolean b = CaptchaService.getInstance().validateCaptcha(code, request.getSession());
if (b) {

// 正确

} else {

// 错误

}
}


P.S: 中文的验证码是能够实现的, 只需要把上面的代码中字体一部分改成

Font f = Font.decode("华文细黑"); //当然其他字体也可以, 但是必须是Server上有的字体

WordGenerator words = new RandomWordGenerator("一二三四五六");

您可能感兴趣的与本文相关的镜像

Qwen-Image

Qwen-Image

图片生成
Qwen

Qwen-Image是阿里云通义千问团队于2025年8月发布的亿参数图像生成基础模型,其最大亮点是强大的复杂文本渲染和精确图像编辑能力,能够生成包含多行、段落级中英文文本的高保真图像

本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值