网站地图    收藏   

主页 > 后端 > php资料库 >

使用JCaptcha生成验证码_自学php网

来源:自学PHP网    时间:2014-12-04 22:12 作者: 阅读:

[导读] 在项目里用JCaptcha添加了验证码. 中间调试费了很多时间, 这里直接把步骤和结果的源代码贴出来吧. 首先要到JCaptcha的官网去下载jar包, 目前使用 jcaptcha-1.0-all.jar 这个就够了, 如果你的l...

在项目里用JCaptcha添加了验证码. 中间调试费了很多时间, 这里直接把步骤和结果的源代码贴出来吧.

首先要到JCaptcha的官网去下载jar包, 目前使用 jcaptcha-1.0-all.jar 这个就够了, 如果你的lib中没有 commons-collections-3.2.1.jar 的话, 需要去 Apache Collections 网站下一个, 因为生成时使用的fasthashmap依赖于这个jar.

JCaptcha 官网上 java doc已经已经更新至2.0alpha版, 但是发布的jar还是1.0, 所以java doc中提到的一些engine在jar中是没有的, 一些deprecated的类在1.0中依然需要使用.

JCaptcha 官网上提供了一个最简单的5分钟速成样例, 直接使用DefaultManageableImageCaptchaService构建验证图.

因为默认的验证图很难辨认, 所以还是需要自己定制一下, 以适应自己项目的需求.

首先是扩展出自己的ImageCaptchaEngine, 命名为 CaptchaImageEngine.java . 这里借鉴了几个网络上前辈提供的例子, 做了一些修改


public class CaptchaImageEngine extends ListImageCaptchaEngine
{
public static final Integer WORD_MIN_LENGTH = new Integer(4);
public static final Integer WORD_MAX_LENGTH = new Integer(4);

public static final Integer IMAGE_WIDTH = new Integer(160);
public static final Integer IMAGE_HEIGHT = new Integer(50);

public static final Integer FONT_MIN_SIZE = new Integer(30);
public static final Integer FONT_MAX_SIZE = new Integer(35);

protected void buildInitialFactories()
{
WordGenerator wordGenerator = (new RandomWordGenerator("23456789ABCDEFGHJKMNPQRSTUVWXY"));

BackgroundGenerator backgroundGenerator = new UniColorBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT);

Font[] fontsList = new Font[]{Font.decode("Arial"), Font.decode("Georgia"), Font.decode("Verdana"), Font.decode("Courier New")};
FontGenerator fontGenerator = new RandomFontGenerator(FONT_MIN_SIZE, FONT_MAX_SIZE, fontsList);

RandomRangeColorGenerator cgen = new RandomRangeColorGenerator(
new int[] { 0, 128 },
new int[] { 0, 128 },
new int[] { 0, 196 }
);

TextDecorator[] textdecorators = new TextDecorator[]{new BaffleTextDecorator(new Integer(1), Color.WHITE)};

TextPaster textPaster = new DecoratedRandomTextPaster(
WORD_MIN_LENGTH,
WORD_MAX_LENGTH,
cgen,
textdecorators
);

WaterFilter water = new WaterFilter();
water.setAmplitude(5d);//振幅
water.setAntialias(true);//锯齿或平滑
water.setPhase(30d);//相位
water.setWavelength(60d);

WordToImage wordToImage = new DeformedComposedWordToImage(
fontGenerator,
backgroundGenerator,
textPaster,
new ImageDeformationByFilters(new ImageFilter[]{}),
new ImageDeformationByFilters(new ImageFilter[]{}),
new ImageDeformationByFilters(new ImageFilter[]{water})
);

addFactory(new GimpyFactory(wordGenerator, wordToImage));
}
}

然后是提供生成验证图的静态方法的 CaptchaService.java . 这里就可以使用刚才建的ImageEngine来绘制验证图了

public class CaptchaService
{
private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService(
new FastHashMapCaptchaStore(),
new CaptchaImageEngine(),
180, 100000, 75000
);

private CaptchaService(){}

public static BufferedImage getImageChallenge(String sid, Locale locale)
{
return instance.getImageChallengeForID(sid, locale);
}

public static BufferedImage getImageChallenge(String sid)
{
return instance.getImageChallengeForID(sid);
}

public static boolean validate(String sid, String input)
{
return instance.validateResponseForID(sid, input);
}
}

这样, 在action中就可以直接调用了, 调用的方法分为两部分, 一部分是生成图片

public String doGenerate()
{
try
{
// 获取session中的token用于生成验证图片,
String token = getSession().getSession_token();

// 生成验证图片
BufferedImage challenge = CaptchaService.getImageChallenge(token);

// 压缩为JPEG格式
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);

// 置入action result的输出数据中
this.put_streambytes("image/jpeg", jpegOutputStream.toByteArray());
}
catch (IllegalArgumentException e)
{
this.put_streambytes("image/jpeg", new byte[]{});
logger.info("IllegalArgumentException");
logger.debug("Exception Details", e);
}
catch (Exception e)
{
this.put_streambytes("image/jpeg", new byte[]{});
logger.info("UnknownException");
logger.debug("Exception Details", e);
}

return SUCCESS;
}

然后, 用于处理action result的方法, 会使用 ServletOutputStream 输出图片

public class StreamProcessor {

private static Logger logger = Logger.getLogger(RawProcessor.class);

public static void process(HttpServletResponse res, String type, Object streamBytes)
{
try
{
res.setHeader("Cache-Control", "no-store");
res.setHeader("Pragma", "no-cache");
res.setDateHeader("Expires", 0);
res.setContentType(type);
ServletOutputStream responseOutputStream = res.getOutputStream();
responseOutputStream.write((byte[])streamBytes);
responseOutputStream.flush();
responseOutputStream.close();
}
catch (Exception e)
{
logger.info("Unknown Exception");
logger.debug("Exception details:", e);
}
}
}

另一方面, 需要在页面上添加对图片的引用, 因为需要制造点击刷新的效果, 使用javascript来生成html引用代码.
前端的HTML是 (


 


其中使用到的回调函数是

function captcha_image(element_id, src)
{
var joiner = '&';
if (src.indexOf('?')== -1) joiner = '?';
$("#"+element_id).html('');
}

后端响应这段js的action, 其作用, 是返回一段js代码, 让浏览器端去调用captcha_image()这个方法来生成引用图片的HTML代码

public String doJsInclude()
{
DefaultRequestBean bean = new DefaultRequestBean();
String elementId = bean.get("element");
String output = "captcha_image(\""+elementId+"\",\""+baseLink("captcha_image")+"\");";
this.put_raw_string(output);
return SUCCESS;
}

在用户提交后, 用于验证用户提交的验证码内容的方法片段:

String token = getSession().getSession_token();
if (!CaptchaService.validate(token, this.captcha_input.toUpperCase()))
{
flag = false;
this.put_error_msg("captcha_input", langRes.get("login_success"));
}
return flag;

 

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论