在Spring中使用jcaptcha实现图片验证

在Spring中使用jcaptcha首先要添加jcaptcha的包 我使用的是jcaptcha-1.0-all.jar 官网http://jcaptcha.sourceforge.net/jcaptcha/index.html

还要添加commons-collections-*.*.jar 版本自己控制

首先是ApplicationContext.xml的配置,这里主要是对验证码生成器服务的注入,控制类就是Spring Web中的Controller,没有什么特别的

<bean id="imageCaptchaService" class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService">  
        <constructor-arg type="com.octo.captcha.service.captchastore.CaptchaStore" index="0">  
            <ref bean="fastHashMapCaptchaStore"/>  
        </constructor-arg>     
        <!--which captcha Engine you use-->     
        <constructor-arg type="com.octo.captcha.engine.CaptchaEngine" index="1">  
            <ref bean="captchaEngineEx"/>  
        </constructor-arg>     
        <constructor-arg index="2">     
            <value>180</value>     
        </constructor-arg>     
        <constructor-arg index="3">     
            <value>100000</value>     
        </constructor-arg>     
        <constructor-arg index="4">     
            <value>75000</value>     
        </constructor-arg>    
    </bean>  
    <bean id="fastHashMapCaptchaStore" 
    	class="com.octo.captcha.service.captchastore.FastHashMapCaptchaStore"/>     
    <!--you can define more than one captcha engine here -->     
    <bean id="captchaEngineEx" 
    	class="com.sha0k.util.CaptchaEngineEx"/>

 下面是验证码生成器CaptchaEngineEx,自己编写:

import java.awt.Color;
import java.awt.Font;
import java.awt.image.ImageFilter;

import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import com.octo.captcha.component.image.color.RandomListColorGenerator;
import com.octo.captcha.component.image.deformation.ImageDeformation;
import com.octo.captcha.component.image.deformation.ImageDeformationByFilters;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.word.wordgenerator.RandomWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;

public class CaptchaEngineEx extends ListImageCaptchaEngine {

	protected void buildInitialFactories() {
		int minWordLength = 4;
		int maxWordLength = 5;
		int fontSize = 50;
		int imageWidth = 250;
		int imageHeight = 100;

		WordGenerator wordGenerator = new RandomWordGenerator(
				"0123456789abcdefghijklmnopqrstuvwxyz");

		TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength,
				maxWordLength, new RandomListColorGenerator(new Color[] {
						new Color(23, 170, 27), new Color(220, 34, 11),
						new Color(23, 67, 172) }), new TextDecorator[] {});
		BackgroundGenerator background = new UniColorBackgroundGenerator(
				imageWidth, imageHeight, Color.white);
		FontGenerator font = new RandomFontGenerator(fontSize, fontSize,
				new Font[] { new Font("nyala", Font.BOLD, fontSize),
						new Font("Bell MT", Font.PLAIN, fontSize),
						new Font("Credit valley", Font.BOLD, fontSize) });

		ImageDeformation postDef = new ImageDeformationByFilters(
				new ImageFilter[] {});
		ImageDeformation backDef = new ImageDeformationByFilters(
				new ImageFilter[] {});
		ImageDeformation textDef = new ImageDeformationByFilters(
				new ImageFilter[] {});

		WordToImage word2image = new DeformedComposedWordToImage(font,
				background, randomPaster, backDef, textDef, postDef);
		addFactory(new GimpyFactory(wordGenerator, word2image));

	}

}

 验证码图片的显示是一个向服务器请求的过程 所以必须有serlvet来处理这个请求,下面是显示验证码的控制器类

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.octo.captcha.service.CaptchaServiceException;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

@Controller
public class GenerateImageController{

	@Resource(name = "imageCaptchaService")
	private ImageCaptchaService imageCaptchaService;

	@RequestMapping(value = "/generatImage")
	public void ImageCaptcha(HttpServletRequest request , HttpServletResponse response , Model model) 
	 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 = request.getSession().getId();
			// call the ImageCaptchaService getChallenge method
			BufferedImage challenge = imageCaptchaService
					.getImageChallengeForID(captchaId, request
							.getLocale());

			// a jpeg encoder
			JPEGImageEncoder jpegEncoder = JPEGCodec
					.createJPEGEncoder(jpegOutputStream);
			jpegEncoder.encode(challenge);
		} catch (IllegalArgumentException e) {
		} catch (CaptchaServiceException e) {
		} catch (ImageFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		captchaChallengeAsJpeg = jpegOutputStream.toByteArray();  
        // flush it in the response  
        response.setHeader("Cache-Control", "no-store");  
        response.setHeader("Pragma", "no-cache");  
        response.setDateHeader("Expires", 0);  
        response.setContentType("image/jpeg");  
        ServletOutputStream responseOutputStream = response  
                .getOutputStream();  
        responseOutputStream.write(captchaChallengeAsJpeg);  
        responseOutputStream.flush();  
        responseOutputStream.close();
	}

}

  而页面的图片显示只要这么简简单单的一句就够了 getimg.jsp页面

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'getimg.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <img alt="" src="generatImage">
  </body>
</html>

验证用户输入的验证码的控制类

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.octo.captcha.service.CaptchaServiceException;
import com.octo.captcha.service.image.ImageCaptchaService;

@Controller
public class ImageValidationController {

	@Resource(name = "imageCaptchaService")
	ImageCaptchaService imageCaptchaService;
	
	@RequestMapping(value = "/validateImage")
	public void ValidateCaptchaImage(HttpServletRequest request,     
            HttpServletResponse response)throws ServletException , IOException {
		Boolean isResponseCorrect = Boolean.FALSE;     
        //remenber that we need an id to validate!     
        String captchaId = request.getSession().getId();     
        //retrieve the response     
        String captcha_value = request.getParameter("captcha_value");     
        // Call the Service method     
        try {     
            isResponseCorrect = imageCaptchaService.validateResponseForID(captchaId, captcha_value);  
        } catch (CaptchaServiceException e) {     
            //should not happen, may be thrown if the id is not valid      
        }     
        System.out.println(isResponseCorrect);   
       // httpServletResponse.encodeUrl("sucess.html");  
        if(isResponseCorrect.booleanValue()){  
        	response.sendRedirect("success.html");  
        }  
        else {  
        	response.sendRedirect("failture.html");  
        }  
    }     
}

 验证页面:

<html>
  <head>
    <base href="<%=basePath%>">
    <script type="text/javascript"
			src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
		<script type="text/javascript"
			src="http://jquery-json.googlecode.com/files/jquery.json-2.2.min.js"></script>
		<script type="text/javascript">
			
				function ajaxRefresh(){  
      
       	 		document.getElementById("image").contentWindow.location.reload();   
    			}  
		
		
		</script>
    
    <title>My JSP 'image.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <iframe src="getimg.jsp" id="image"></iframe>
    <a href="javascript:void(0)" onclick="ajaxRefresh()">ajaxRefresh</a>
    <form action="validateImage">
    	<input type='text' name='captcha_value'>
    	<input type="submit" value="提交">
    </form> 
  </body>
</html>
 

相关推荐