jcaptcha 用法

来源:互联网 发布:网络回环测试 编辑:程序博客网 时间:2024/04/29 12:43

    首先来看看示例的目录结构:

     
        

 

       在Jcaptcha的官方文档中有一个 5分钟快速入门的文章, 是介绍快速开发的文章。 有兴趣的可以去上面看看。

      这里我发上我的源代码:

 

 

     web.xml中:

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <!DOCTYPE web-app  
  4.     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
  5.     "http://java.sun.com/dtd/web-app_2_3.dtd">  
  6. <web-app>  
  7.   
  8.     <servlet>  
  9.         <servlet-name>jcaptcha</servlet-name>  
  10.         <servlet-class>com.ivan.zhang.servlet.ImageCaptchaServlet</servlet-class>  
  11.         <load-on-startup>0</load-on-startup>  
  12.     </servlet>  
  13.     <servlet-mapping>  
  14.         <servlet-name>jcaptcha</servlet-name>  
  15.         <url-pattern>/jcaptcha</url-pattern>  
  16.     </servlet-mapping>   
  17. </web-app>  

 

    再需要一个服务类,用来产生Image Service类:

 

Java代码  收藏代码
  1. package com.ivan.zhang.servlet;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4. import java.io.ByteArrayOutputStream;  
  5. import java.io.IOException;  
  6.   
  7. import javax.imageio.ImageIO;  
  8. import javax.servlet.ServletConfig;  
  9. import javax.servlet.ServletException;  
  10. import javax.servlet.ServletOutputStream;  
  11. import javax.servlet.http.HttpServlet;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15. import com.ivan.zhang.CaptchaServiceSingleton;  
  16. import com.octo.captcha.service.CaptchaServiceException;  
  17. import com.sun.image.codec.jpeg.JPEGCodec;  
  18. import com.sun.image.codec.jpeg.JPEGImageEncoder;  
  19.   
  20. public class ImageCaptchaServlet extends HttpServlet {  
  21.   
  22.     /** 
  23.      *  
  24.      */  
  25.     private static final long serialVersionUID = 1L;  
  26.   
  27.     public void init(ServletConfig servletConfig) throws ServletException {  
  28.         super.init(servletConfig);  
  29.     }  
  30.   
  31.     protected void doGet(HttpServletRequest httpServletRequest,  
  32.             HttpServletResponse httpServletResponse) throws ServletException,  
  33.             IOException {  
  34.   
  35.         byte[] captchaChallengeAsJpeg = null;  
  36.         // the output stream to render the captcha image as jpeg into  
  37.         ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();  
  38.         try {  
  39.             // get the session id that will identify the generated captcha.  
  40.             // the same id must be used to validate the response, the session id  
  41.             // is a good candidate!  
  42.             String captchaId = httpServletRequest.getSession().getId();  
  43.             // call the ImageCaptchaService getChallenge method  
  44.             BufferedImage challenge = CaptchaServiceSingleton.getInstance()  
  45.                     .getImageChallengeForID(captchaId,  
  46.                             httpServletRequest.getLocale());  
  47.   
  48.             // a jpeg encoder  
  49.             JPEGImageEncoder jpegEncoder = JPEGCodec  
  50.                     .createJPEGEncoder(jpegOutputStream);  
  51.             jpegEncoder.encode(challenge);  
  52.         } catch (IllegalArgumentException e) {  
  53.             httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);  
  54.             return;  
  55.         } catch (CaptchaServiceException e) {  
  56.             httpServletResponse  
  57.                     .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);  
  58.             return;  
  59.         }  
  60.         captchaChallengeAsJpeg = jpegOutputStream.toByteArray();  
  61.         // flush it in the response  
  62.         httpServletResponse.setHeader("Cache-Control""no-store");  
  63.         httpServletResponse.setHeader("Pragma""no-cache");  
  64.         httpServletResponse.setDateHeader("Expires"0);  
  65.         httpServletResponse.setContentType("image/jpeg");  
  66.         ServletOutputStream responseOutputStream = httpServletResponse  
  67.                 .getOutputStream();  
  68.         responseOutputStream.write(captchaChallengeAsJpeg);  
  69.           
  70.         responseOutputStream.flush();  
  71.         responseOutputStream.close();  
  72.     }  
  73. }  
 

   OK,后台的类写完了, 现在我们来看看前台页面的编写:

 

   index.jsp

Java代码  收藏代码
  1. <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <title>Insert title here</title>  
  8. </head>  
  9. <body>  
  10. <form action="sample.jsp">  
  11.     <img src="jcaptcha">  
  12.     <input type='text' name='j_captcha_response' value=''>  
  13. </form>  
  14. </body>  
  15. </html>  

 

    sample.jsp: (用来验证的页面 )

 

Java代码  收藏代码
  1. <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@page import="com.octo.captcha.service.CaptchaServiceException"%>  
  4. <%@page import="com.ivan.zhang.CaptchaServiceSingleton"%>  
  5. <%  
  6.     Boolean isResponseCorrect = Boolean.FALSE;  
  7.     //remenber that we need an id to validate!  
  8.     String captchaId = request.getSession().getId();  
  9.     //retrieve the response  
  10.     String responsestr = request.getParameter("j_captcha_response");  
  11.     // Call the Service method  
  12.     try {  
  13.         isResponseCorrect = CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId, responsestr);  
  14.         if(isResponseCorrect){  
  15.               
  16.         }else{  
  17.             out.print("It's worng......");  
  18.         }  
  19.     } catch (CaptchaServiceException e) {  
  20.         //should not happen, may be thrown if the id is not valid  
  21.     }  
  22. %>  
 

   这样,我们的第一个版本出来了, 我们来看看效果:

    

 

  我们看到, 虽然生成了验证码,但是这样的图片给人非常不友好的感觉,  所以我参考Springside中的一样,自己给他设定产生图片的样式:

   要实现自定义样式,我们需要一下2个步骤: 

   1. 告诉Jcaptcha 我要的样式是什么样子.

   2. 在提交后,利用我们自己的样式来产生图片.

 

  所以,我们改动一下 :

    新加一个类GmailEngine.java(直接拿至Springside ,非常感谢白衣的共享,让我们这样的菜鸟学到很多东西.)

    

 

  其中代码如下:

 

Java代码  收藏代码
  1. package com.ivan.zhang.servlet;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.Font;  
  5. import java.awt.image.ImageFilter;  
  6.   
  7. import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;  
  8. import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;  
  9. import com.octo.captcha.component.image.color.RandomListColorGenerator;  
  10. import com.octo.captcha.component.image.deformation.ImageDeformation;  
  11. import com.octo.captcha.component.image.deformation.ImageDeformationByFilters;  
  12. import com.octo.captcha.component.image.fontgenerator.FontGenerator;  
  13. import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;  
  14. import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;  
  15. import com.octo.captcha.component.image.textpaster.TextPaster;  
  16. import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;  
  17. import com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;  
  18. import com.octo.captcha.component.image.wordtoimage.WordToImage;  
  19. import com.octo.captcha.component.word.FileDictionary;  
  20. import com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;  
  21. import com.octo.captcha.component.word.wordgenerator.WordGenerator;  
  22. import com.octo.captcha.engine.image.ListImageCaptchaEngine;  
  23. import com.octo.captcha.image.gimpy.GimpyFactory;  
  24.   
  25. /** 
  26.  * 仿照JCaptcha2.0编写GMail验证码样式的图片引擎. 
  27.  *  
  28.  * @author calvin 
  29.  */  
  30. public class GMailEngine extends ListImageCaptchaEngine {  
  31.     @Override  
  32.     protected void buildInitialFactories() {  
  33.         int minWordLength = 4;  
  34.         int maxWordLength = 5;  
  35.         int fontSize = 50;  
  36.         int imageWidth = 250;  
  37.         int imageHeight = 100;  
  38.   
  39.         //word generator  
  40.         WordGenerator dictionnaryWords = new ComposeDictionaryWordGenerator(new FileDictionary("toddlist"));  
  41.   
  42.         //word2image components  
  43.         TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength, maxWordLength,  
  44.                 new RandomListColorGenerator(new Color[] { new Color(2317027), new Color(2203411),  
  45.                         new Color(2367172) }), new TextDecorator[] {});  
  46.         BackgroundGenerator background = new UniColorBackgroundGenerator(imageWidth, imageHeight, Color.white);  
  47.         FontGenerator font = new RandomFontGenerator(fontSize, fontSize, new Font[] {  
  48.                 new Font("nyala", Font.BOLD, fontSize), new Font("Bell MT", Font.PLAIN, fontSize),  
  49.                 new Font("Credit valley", Font.BOLD, fontSize) });  
  50.   
  51.         ImageDeformation postDef = new ImageDeformationByFilters(new ImageFilter[] {});  
  52.         ImageDeformation backDef = new ImageDeformationByFilters(new ImageFilter[] {});  
  53.         ImageDeformation textDef = new ImageDeformationByFilters(new ImageFilter[] {});  
  54.   
  55.         WordToImage word2image = new DeformedComposedWordToImage(font, background, randomPaster, backDef, textDef,  
  56.                 postDef);  
  57.         addFactory(new GimpyFactory(dictionnaryWords, word2image));  
  58.     }  
  59.   
  60. }  
 

   如果有玩过Swing的兄弟,应该会很好理解上面的代码。

 

   继续,我们有了自己的样式类, 接下来我们就要告诉servlet我们需要用哪个样式生成图片。

   就有如下,将CaptchaServiceSingleton类修改一下:

 

Java代码  收藏代码
  1. package com.ivan.zhang;  
  2.   
  3. import com.ivan.zhang.servlet.GMailEngine;  
  4. import com.octo.captcha.engine.GenericCaptchaEngine;  
  5. import com.octo.captcha.service.CaptchaService;  
  6. import com.octo.captcha.service.captchastore.FastHashMapCaptchaStore;  
  7. import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;  
  8. import com.octo.captcha.service.image.ImageCaptchaService;  
  9.   
  10. /** 
  11.  * 按照官方的做法: 一定为单例 
  12.  * @author Administrator 
  13.  * 
  14.  */  
  15. public class CaptchaServiceSingleton {  
  16.      private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService(  
  17.                new FastHashMapCaptchaStore(), new GMailEngine(), 180,  
  18.                100000 , 75000);  
  19.     public static ImageCaptchaService getInstance(){  
  20.         return instance;  
  21.     }  
  22. }  
 

    同样的,修改一下Servlet类:

 

    改动如下:

 

Java代码  收藏代码
  1. package com.ivan.zhang.servlet;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4. import java.io.ByteArrayOutputStream;  
  5. import java.io.IOException;  
  6.   
  7. import javax.imageio.ImageIO;  
  8. import javax.servlet.ServletConfig;  
  9. import javax.servlet.ServletException;  
  10. import javax.servlet.ServletOutputStream;  
  11. import javax.servlet.http.HttpServlet;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15. import com.ivan.zhang.CaptchaServiceSingleton;  
  16. import com.octo.captcha.service.CaptchaServiceException;  
  17. import com.sun.image.codec.jpeg.JPEGCodec;  
  18. import com.sun.image.codec.jpeg.JPEGImageEncoder;  
  19.   
  20. public class ImageCaptchaServlet extends HttpServlet {  
  21.   
  22.     /** 
  23.      *  
  24.      */  
  25.     private static final long serialVersionUID = 1L;  
  26.   
  27.     public void init(ServletConfig servletConfig) throws ServletException {  
  28.         super.init(servletConfig);  
  29.     }  
  30.   
  31.     protected void doGet(HttpServletRequest httpServletRequest,  
  32.             HttpServletResponse httpServletResponse) throws ServletException,  
  33.             IOException {  
  34.         genernateCaptchaImage(httpServletRequest, httpServletResponse);  
  35.     }  
  36.       
  37.       
  38.     /** 
  39.      * 生成验证码图片. 
  40.      */  
  41.     private void genernateCaptchaImage(final HttpServletRequest request, final HttpServletResponse response)  
  42.             throws IOException {  
  43.         response.setHeader("Cache-Control""no-store");  
  44.         response.setHeader("Pragma""no-cache");  
  45.         response.setDateHeader("Expires"0);  
  46.         response.setContentType("image/jpeg");  
  47.         ServletOutputStream out = response.getOutputStream();  
  48.         try {  
  49.             String captchaId = request.getSession(true).getId();  
  50.             BufferedImage challenge = (BufferedImage)  CaptchaServiceSingleton.getInstance().getChallengeForID(captchaId, request.getLocale());  
  51.             ImageIO.write(challenge, "jpg", out);  
  52.             out.flush();  
  53.         } catch (CaptchaServiceException e) {  
  54.         } finally {  
  55.             out.close();  
  56.         }  
  57.     }  
  58. }  

 

  OK, 这样我们产生的图片样式就会好看多了。 不相信?  OK, 非要上图才有人相信。

    截图如下:



    再来一下刷新:

    

0 0
原创粉丝点击