这个验证码的使用灰常简单,只有三个类可以直接copy,然后再配置一下web.xml,然后就可以在你的java登录验证类里使用了
这时效果图:
需要引入jcapthca-1.0-all.jar包
生产图片的javal类,需要集成HttpServlet
/**
* @ClassName: ImageCaptchaServlet
* @author YangXuan
* @date Aug 4, 2013 7:07:39 PM
*/
@SuppressWarnings("serial")
public class ImageCaptchaServlet extends HttpServlet {
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
}
protected void doGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws ServletException,
IOException {
byte[] captchaChallengeAsJpeg = null;
// the output stream to render the captcha image as jpeg into
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
// get the session id that will identify the generated captcha.
// the same id must be used to validate the response, the session id
// is a good candidate!
String captchaId = httpServletRequest.getSession().getId();
// call the ImageCaptchaService getChallenge method
BufferedImage challenge = CaptchaServiceSingleton.getInstance()
.getImageChallengeForID(captchaId,
httpServletRequest.getLocale());
// a jpeg encoder
JPEGImageEncoder jpegEncoder = JPEGCodec
.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);
} catch (IllegalArgumentException e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} catch (CaptchaServiceException e) {
httpServletResponse
.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
// flush it in the response
httpServletResponse.setHeader("Cache-Control", "no-store");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream = httpServletResponse
.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
}
可以根据需要扩展这个验证码的样式
/**
* @ClassName: ImageCaptchaEngineExtend
* @author YangXuan
* @date Aug 4, 2013 7:10:35 PM
*/
public class ImageCaptchaEngineExtend extends ListImageCaptchaEngine {
protected void buildInitialFactories() {
int minWordLength = 4;
int maxWordLength = 4;
int fontSize = 50;
int imageWidth = 180;
int imageHeight = 50;
// build filters
WaterFilter water = new WaterFilter();
water.setAmplitude(3d);//振幅
water.setAntialias(true);//锯齿或平滑
water.setPhase(20d);//相位
water.setWavelength(70d);//波长
//backgroundDeformation 背景图变形
ImageDeformation backDef = new ImageDeformationByFilters(
new ImageFilter[] {});
//textDeformation 字符图层转变形
ImageDeformation textDef = new ImageDeformationByFilters(
new ImageFilter[] {});
//finalDeformation 最终图片变形
ImageDeformation postDef = new ImageDeformationByFilters(
new ImageFilter[] { water });
//生成单词
WordGenerator dictionnaryWords = new RandomWordGenerator(
"abcdefhjkmnprstuvwxyz23456789");
// wordtoimage components
RandomRangeColorGenerator colors = new RandomRangeColorGenerator(
new int[] { 0, 150 }, new int[] { 0, 150 },
new int[] { 0, 150 });
// 显示的字体设置,Arial,Tahoma,Verdana,Helvetica,宋体,黑体,幼圆
Font[] fonts = new Font[] { new Font("Arial", 0, fontSize),
new Font("Tahoma", 0, fontSize),
new Font("Verdana", 0, fontSize),
new Font("Helvetica", 0, fontSize),
new Font("宋体", 0, fontSize), new Font("黑体", 0, fontSize),
new Font("幼圆", 0, fontSize) };
// 设置字符以及干扰线
/*
* RandomRangeColorGenerator lineColors = new RandomRangeColorGenerator(
* new int[] { 150, 255 }, new int[] { 150, 255 }, new int[] { 150, 255
* });
*/
/*
* TextPaster randomPaster = new DecoratedRandomTextPaster(new
* Integer(4), new Integer(4), colors, true, new TextDecorator[] { new
* LineTextDecorator(new Integer(1), lineColors) });
*/
// 文字显示的个数
TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength,
maxWordLength, colors, true, new TextDecorator[] {});
//背景图生成
BackgroundGenerator back = new UniColorBackgroundGenerator(imageWidth,
imageHeight, Color.white);
//字体生成
FontGenerator shearedFont = new RandomFontGenerator(new Integer(30),
new Integer(0), fonts);
// word2image 1
WordToImage word2image;
word2image = new DeformedComposedWordToImage(shearedFont, back,
randomPaster, backDef, textDef, postDef);
this.addFactory(new GimpyFactory(dictionnaryWords, word2image));
}
}
/**
* @ClassName: CaptchaServiceSingleton
* @author YangXuan
* @date Aug 4, 2013 7:11:05 PM
*/
public class CaptchaServiceSingleton {
// 不允许构造实例
private CaptchaServiceSingleton() {
}
private static ImageCaptchaService instance = null;
// 传入样式类
static {
instance = new DefaultManageableImageCaptchaService(
new FastHashMapCaptchaStore(), new ImageCaptchaEngineExtend(),
180, 100000, 75000);
}
public static ImageCaptchaService getInstance() {
return instance;
}
}
以上三个类可以直接copy拿来做工具,接下来是配置如何实现验证
在web.xml中配置servlet获取让前台获取到图片
<!-- jcaptcha -->
<servlet>
<servlet-name>jcaptcha</servlet-name>
<servlet-class>com.yang.Jcaptcha.ImageCaptchaServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jcaptcha</servlet-name>
<url-pattern>/jcaptcha</url-pattern>
</servlet-mapping>
前台页面:
<img class="controls" src="jcaptcha" id="checkCodeImg"
οnclick="this.src='jcaptcha?now=' + new Date().getTime()"
alt="看不清?点击换一张" title="click to change" style="cursor:pointer"
width="130" />
最后是如何验证输入的验证码是否正确,将它封装成一个方法
public void checkValidateCode(HttpServletRequest request) {
String jcaptchaCode = obtainValidationString(request).trim()
.toUpperCase(); //获取前台的验证码输入值
if (null == jcaptchaCode || jcaptchaCode.equals(""))
throw new BadCredentialsException("验证码超时!!!");
boolean b = CaptchaServiceSingleton.getInstance()
.validateResponseForID(request.getSession().getId(),
jcaptchaCode);
if (!b)
throw new BadCredentialsException("验证码不匹配!!!");
}