`
easy0917
  • 浏览: 261050 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

使用 jcaptcha 产生图片校验码

 
阅读更多
第一步:下载 jcaptcha-all-1.0-RC2.0.1.jar
第二步:代码实现
CaptchaServiceSingleton.java

package com.yh.web.jcaptcha;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.GradientBackgroundGenerator;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.RandomTextPaster;
import com.octo.captcha.component.image.textpaster.SimpleTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.wordgenerator.RandomWordGenerator;
import com.octo.captcha.component.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.ImageCaptcha;
import com.octo.captcha.image.ImageCaptchaFactory;
import com.octo.captcha.image.gimpy.GimpyFactory;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class CaptchaServiceSingleton extends ListImageCaptchaEngine {
	private static Logger log = Logger.getLogger(CaptchaServiceSingleton.class);
	private static final Integer MIN_WORD_LENGTH = new Integer(4);
	private static final Integer MAX_WORD_LENGTH = new Integer(6);
	private static final Integer IMAGE_WIDTH = new Integer(70);
	private static final Integer IMAGE_HEIGHT = new Integer(20);
	private static final Integer MIN_FONT_SIZE = new Integer(12);
	private static final Integer MAX_FONT_SIZE = new Integer(14);
	private static final String NUMERIC_CHARS = "23456789";// No numeric 0
	private static final String UPPER_ASCII_CHARS = "ABCDEFGHJKLMNPQRSTXYZ";// No

	// upper
	// O I

	// we dont use the lower characters because it cause dificult in some case,
	// so that
	// we must always UPPERCASE the input from user (currently in
	// OnlineUserImpl)
	private static final String LOWER_ASCII_CHARS = "abcdefghjkmnpqrstxyz";// No

	// lower
	// o i

	/**
	 * Singleton instance of this class
	 */
	private static CaptchaServiceSingleton instance = new CaptchaServiceSingleton();

	private ArrayList textPasterList;

	private ArrayList backgroundGeneratorList;

	private ArrayList fontGeneratorList;

	ImageCaptcha imageCaptcha = null;

	/**
	 * Private constructor to prevent instantiation
	 */
	private CaptchaServiceSingleton() {
	}

	public static CaptchaServiceSingleton getInstance() {
		return instance;
	}

	protected void buildInitialFactories() {
		try {
			textPasterList = new ArrayList();
			backgroundGeneratorList = new ArrayList();
			fontGeneratorList = new ArrayList();

			textPasterList.add(new SimpleTextPaster(MIN_WORD_LENGTH,
					MAX_WORD_LENGTH, Color.black));
			textPasterList.add(new RandomTextPaster(MIN_WORD_LENGTH,
					MAX_WORD_LENGTH, Color.black));
			textPasterList.add(new SimpleTextPaster(MIN_WORD_LENGTH,
					MAX_WORD_LENGTH, Color.black));
			textPasterList.add(new RandomTextPaster(MIN_WORD_LENGTH,
					MAX_WORD_LENGTH, Color.black));
			textPasterList.add(new SimpleTextPaster(MIN_WORD_LENGTH,
					MAX_WORD_LENGTH, Color.blue));
			textPasterList.add(new RandomTextPaster(MIN_WORD_LENGTH,
					MAX_WORD_LENGTH, Color.blue));

			backgroundGeneratorList.add(new GradientBackgroundGenerator(
					IMAGE_WIDTH, IMAGE_HEIGHT, Color.orange, Color.white));
			backgroundGeneratorList.add(new GradientBackgroundGenerator(
					IMAGE_WIDTH, IMAGE_HEIGHT, Color.white, Color.green));
			backgroundGeneratorList.add(new GradientBackgroundGenerator(
					IMAGE_WIDTH, IMAGE_HEIGHT, Color.gray, Color.white));
			backgroundGeneratorList.add(new GradientBackgroundGenerator(
					IMAGE_WIDTH, IMAGE_HEIGHT, Color.white, Color.orange));
			backgroundGeneratorList.add(new GradientBackgroundGenerator(
					IMAGE_WIDTH, IMAGE_HEIGHT, Color.green, Color.white));
			backgroundGeneratorList.add(new GradientBackgroundGenerator(
					IMAGE_WIDTH, IMAGE_HEIGHT, Color.yellow, Color.white));
			backgroundGeneratorList.add(new GradientBackgroundGenerator(
					IMAGE_WIDTH, IMAGE_HEIGHT, Color.white, Color.magenta));

			

			// fontGeneratorList.add(new
			// TwistedAndShearedRandomFontGenerator(MIN_FONT_SIZE,
			// MAX_FONT_SIZE));
			// fontGeneratorList.add(new
			// TwistedRandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE));// link
			// character too much
			fontGeneratorList.add(new RandomFontGenerator(MIN_FONT_SIZE,
					MAX_FONT_SIZE));// to easy to read
			// fontGeneratorList.add(new
			// DeformedRandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE));// to
			// small font

			// no char upper O, char lower o and numerric 0 because user cannot
			// answer
			WordGenerator words = new RandomWordGenerator(NUMERIC_CHARS
					+ UPPER_ASCII_CHARS);

			for (Iterator fontIter = fontGeneratorList.iterator(); fontIter
					.hasNext();) {
				FontGenerator font = (FontGenerator) fontIter.next();
				for (Iterator backIter = backgroundGeneratorList.iterator(); backIter
						.hasNext();) {
					BackgroundGenerator back = (BackgroundGenerator) backIter
							.next();
					for (Iterator textIter = textPasterList.iterator(); textIter
							.hasNext();) {
						TextPaster parser = (TextPaster) textIter.next();

						WordToImage word2image = new ComposedWordToImage(font,
								back, parser);
						ImageCaptchaFactory factory = new GimpyFactory(words,
								word2image);
						addFactory(factory);
					}
				}
			}
		} catch (Exception ex) {
			log.error("产生校验码初始化异常 == " + ex);
			// throw ex;
		}
	}

	/**
	 * Write the captcha image of current user to the servlet response
	 * 
	 * @param request
	 *            HttpServletRequest
	 * @param response
	 *            HttpServletResponse
	 * @throws IOException
	 */
	public void writeCaptchaImage(HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		imageCaptcha = getNextImageCaptcha();
		HttpSession session = request.getSession();
		session.setAttribute("imageCaptcha", imageCaptcha);
		BufferedImage image = (BufferedImage) imageCaptcha.getChallenge();

		OutputStream outputStream = null;
		try {
			outputStream = response.getOutputStream();
			// render the captcha challenge as a JPEG image in the response
			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();
			outputStream.close();
			outputStream = null;// no close twice
		} catch (IOException ex) {
			log.error("产生图片异常 == " + ex);
			throw ex;
		} finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException ex) {
				}
			}
			imageCaptcha.disposeChallenge();
		}
	}

	public boolean validateCaptchaResponse(String validateCode,
			HttpSession session) {
		boolean flag = true;
		try {
			imageCaptcha = (ImageCaptcha) session.getAttribute("imageCaptcha");
			if (imageCaptcha == null) {
				// log.info("validateCaptchaResponse returned false due to
				// imageCaptcha is null");
				flag = false;
			}
			//validateCode = validateCode.toLowerCase();// use upper case for
			validateCode = validateCode.toUpperCase();// use upper case for
			// easier usage
flag = (imageCaptcha.validateResponse(validateCode)).booleanValue();
			session.removeAttribute("imageCaptcha");
			return flag;
		} catch (Exception ex) {
			ex.printStackTrace();
			log.error("校验码校验异常 == " + ex);
			return false;
		}
	}
	
}
ImageCaptchaServlet.java


package com.yh.web.servlet;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.yh.web.jcaptcha.CaptchaServiceSingleton;
import com.octo.captcha.service.CaptchaServiceException;

public class ImageCaptchaServlet extends HttpServlet {

	private static final long serialVersionUID = -5382766069139170499L;
	public void init(ServletConfig servletConfig) throws ServletException {

		super.init(servletConfig);

	}

	protected void doGet(HttpServletRequest httpServletRequest,
			HttpServletResponse httpServletResponse) throws ServletException,
			IOException {
		System.out.println("---------- ImageCaptchaServlet pass here -------------");
		try {
			CaptchaServiceSingleton.getInstance().writeCaptchaImage(
					httpServletRequest, httpServletResponse);

		} catch (IllegalArgumentException e) {
			httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
			return;
		} catch (CaptchaServiceException e) {
			httpServletResponse
					.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			return;
		}
	}
}
jsp页面增加校验码内容:
<tr><td> 
校验码:<input type="text" size="8" name="checkCode" id="checkCode" class="normal_input"/><img src="/jcaptcha" id="checkCodeImg" onclick="this.src='/jcaptcha?now=' + new Date().getTime()" alt="看不清,点击换一张" >请输入校验码,大小写不区分<br> 如看不清,请点击图片换一张 
</td></tr> 
判断校验码是否正确的java代码:

Java代码 
HttpSession session = request.getSession();      
boolean isResponseCorrect = false;      
// retrieve the response      
String validateCode = checkCode.trim();      
System.out.println("checkCode == "     
        + checkCode);      
try {      
    isResponseCorrect = CaptchaServiceSingleton.getInstance()      
       .validateCaptchaResponse(validateCode, session);      
     
    return isResponseCorrect;      
} catch (Exception e) {      
    // should not happen, may be thrown if the id is not valid      
     
    return false;      
分享到:
评论

相关推荐

    SpringMVC中使用Jcaptcha实现校验码验证

    - **无法存储于Session**:由于Session在分布式环境中难以共享,这限制了Jcaptcha在集群环境中的使用。为解决这个问题,开发者需要寻找其他跨服务器的解决方案,如使用统一的会话管理服务或者基于数据库的会话存储。...

    BMP图片校验码识别

    在"BMP图片校验码识别"这个主题中,我们主要关注的是如何验证和识别这种图片文件中的校验码。校验码通常用于确保数据的完整性和正确性,特别是在传输或存储过程中防止错误。 在256色的BMP图片中,每个像素由8位表示...

    LRC校验码生成器_LRC校验码生成器_

    LRC(Low Redundancy Checksum)校验码是一种简单的错误检测机制,常用于音频文件的歌词同步数据中。在本文中,我们将深入探讨LRC校验码的原理、生成方法以及C++实现的细节。 LRC校验码的原理: LRC校验码是一种逐...

    串口通信CRC校验码得计算方法

    其次,对每个小序列计算CRC校验码,使用 GF(2)多项式算术对小序列进行计算,得到一个 CRC 校验码。 最后,将所有的小序列的校验码组合成一个完整的CRC校验码,这个完整的CRC校验码就是最终的CRC校验码。 CRC 校验...

    CRC校验码计算小工具

    "说明.txt"可能包含关于如何使用CRC计算器及解释MODBUS协议中CRC校验码的详细步骤和注意事项。"bs_out.txt"和"bs_in.txt"可能分别代表的是经过CRC校验的数据输出文件和原始输入文件,它们可以用于测试CRC计算的正确...

    Java 生成校验码及校验码判断

    在实际的Web应用中,`校验码使用说明`文档可能会详细阐述如何集成这些服务到Spring MVC、Struts2或其他Web框架,以及如何在前端页面上展示和处理校验码。同时,该文档还可能包含错误处理和异常情况的处理策略,确保...

    CRC16校验码计算工具

    这个过程会产生一个余数,即CRC校验码,将其附加到原始数据的末尾。接收端同样使用该生成多项式对收到的数据进行除法运算,如果余数为零,则认为数据传输无误;若不为零,则可能存在错误。 CRC16校验码的“16”表示...

    C# CRC 16 校验码生成

    CRC16是CRC的一种,它使用16位的校验码。在C#中实现CRC16校验码生成,主要涉及以下几个核心知识点: 1. **CRC原理**:CRC的基本思想是通过附加一个固定长度的校验码来检测数据中的错误。这个校验码是根据数据按位...

    16进制和ASCII码校验码计算工具

    在实际使用中,例如,如果你是一个软件开发者,你可以用这个工具来检查你的程序或文件的CRC校验码,确保在分发或更新时数据的完整性。或者,如果你在处理网络通信,可以计算并验证数据包的CRC,以减少因通信错误导致...

    奇偶校验码,海明校验码,CRC校验码

    奇偶校验码、海明校验码、CRC校验码 奇偶校验码是最简单的检验码,它可以检测奇数位错误,但无法检测偶数位错误,也无法检测出哪位出错。奇偶校验码分为奇校验码和偶校验码两种。奇校验码加上校验位后,编码中1的...

    CRC校验码计算器(包含8位16位32位)

    使用CRC校验码计算器,用户无需理解CRC的复杂计算过程,只需提供待校验的数据,即可快速得到相应的CRC值,从而判断数据的完整性。 TestCRC.exe作为压缩包内的文件,很可能是这个CRC校验码计算器的可执行程序。用户...

    CRC16校验码计算器

    当开发者需要发送一串数据时,他们可以使用这个计算器输入完整的数据帧,计算器将自动计算出对应的CRC16校验码,并将其添加到数据帧末尾。 CRC16的计算过程涉及以下几个关键步骤: 1. **选择多项式**:每个CRC算法...

    Modbus-RTU CRC16校验码计算器

    在Modbus-RTU通信中,为了确保数据传输的准确性,使用了循环冗余校验(CRC)作为错误检测机制。CRC校验码是一种广泛采用的校验方法,能够有效地检测出数据传输过程中的错误。 CRC校验码的基本原理是通过一个预先...

    checkcode生成文件_checkcode_校验码_

    开发者可能还会使用时间戳或者特定种子值来确保每次请求的校验码不一致。 2. **编码转换**:随机数据可能需要进行编码转换,比如ASCII到十六进制,以得到更复杂且难以猜测的字符串。 3. **图像化**:为了防止自动...

    数据校验码(奇偶校验码 海明校验码 循环冗余校验码)

    CRC的基本思想是将数据视为一个大二进制数,这个数通过除以一个预先定义的生成多项式,产生一个较小的余数,即为CRC校验码。发送方将这个校验码附加到原始数据后面一起发送。接收方收到数据后,使用相同的生成多项式...

    16进制指令求和校验码计算器

    之前上传了一份,可能是因为用VS2019编译的,一些电脑上无法运行,缺少对应的动态库, 所以重新用Dev C++编译了一下,这个经过在那些不...如果需要保留计算过的指令集和校验码,务必在使用完成后将文件备份到其他文件夹

    ModbusCrc16校验码计算工具

    使用此工具时,你只需提供要校验的数据,程序会自动完成以上步骤,生成对应的CRC16校验码。在实际的Modbus通信中,这个校验码会被附加到数据的末尾,接收方在接收到数据后,也会执行相同的CRC计算,如果计算出的校验...

Global site tag (gtag.js) - Google Analytics