当前位置: 代码迷 >> Web前端 >> 施用jcaptcha 仿论坛tip 生成异步验证码
  详细解决方案

施用jcaptcha 仿论坛tip 生成异步验证码

热度:181   发布时间:2012-11-25 11:44:31.0
使用jcaptcha 仿论坛tip 生成异步验证码

首先看看效果图:

?

如上图,点击验证码可以异步的刷新,借助了一个Jquery插件――jquery.qtip插件,和jcaptcha 配置生成验证码。

?

1.先配置好,能生成jcaptcha的环境,

在web.xml中添加如下内容:

<servlet>

		<servlet-name>jcaptcha2</servlet-name>
		<servlet-class>com.jxs.sys.core.global.jcaptcha.ImageCaptchaServlet</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>jcaptcha2</servlet-name>
		<url-pattern>/jcaptcha</url-pattern>
	</servlet-mapping>

?2.设置Servlet和regx,

?

package com.jxs.sys.core.global.jcaptcha;

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

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

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

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

@SuppressWarnings("serial")
public class ImageCaptchaServlet extends HttpServlet {
	private ImageCaptchaService imageCaptchaService;
	private String beanName = "imageCaptchaService";

	public void init(ServletConfig servletConfig) throws ServletException {
		super.init(servletConfig);
		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletConfig.getServletContext());
		imageCaptchaService = (ImageCaptchaService) wac.getBean(beanName, ImageCaptchaService.class);
	}

	protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {

		byte[] captchaChallengeAsJpeg = null;
		ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
		try {
			String captchaId = httpServletRequest.getSession().getId();
			BufferedImage challenge = imageCaptchaService.getImageChallengeForID(captchaId, httpServletRequest.getLocale());

			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();

		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();
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		super.doGet(req, resp);
	}

}
?

?

其他的代码,参见下载:jcaptcha_src.rar,

?

2.借助jquery去完成核心的代码。

首先设置logo.jsp

?

		<script type="text/javascript" src="js/jquery-1.3.2.js"></script>
		<script type="text/javascript" src="js/jquery.qtip-1.0.0-rc3.min.js"></script>
		<script type="text/javascript">
			var contextPath = '${pageContext.request.contextPath}';
		</script>
		<script type="text/javascript" src="js/jcaptcha.js"></script>
?

?

接下来就是要完成jcaptcha.js文件。

代码先给出,在解释:

?

var $j = jQuery.noConflict();
var realoadRandom = Math.random();
function refreshLoadRandom(obj, src){
    realoadRandom = Math.random();
    obj.src = src + "&amp;ran=" + realoadRandom;
}

$j(document).ready(function(){
    var i, styles, tooltipCount;
    tooltipCount = 0;
    styles = ['blue'];
    function createTooltip(){
        if (++tooltipCount == styles.length + 1) 
            return;
        this.elements.tooltip.qtip({
            content: '<img align=\"middle\" style=\"text-align: center; cursor: pointer;\" src=\"' + contextPath + '/jcaptcha\" onclick=\"this.src=\'' + contextPath + '/jcaptcha?now=' +
            realoadRandom +
            '\';refreshLoadRandom(this,\'' +
            contextPath +
            '/jcaptcha?nowa=nk\');\" alt=\"看不清,点击换一张\"/>',
            position: {
                corner: {
                    tooltip: 'leftMiddle',
                    target: 'rightMiddle'
                },
                adjust: {
                    resize: true,
                    scroll: true
                }
            },
            show: {
                ready: true
            },
            hide: false,
            style: {
                name: styles[tooltipCount - 1],
                width: 107,
                height: 30,
                size: {
                    x: 12,
                    y: 12
                },
                tip: true
            },
            api: {
                onRender: createTooltip
            }
        });
    }
    createTooltip.call({
        elements: {
            tooltip: $j('#j_captcha_response')
        }
    });
    $j('#j_username').qtip({
        position: {
            corner: {
                target: 'topMiddle',
                tooltip: 'bottomMiddle'
            }
        },
        content: "请在此输入您的用户名!",
        style: {
            name: 'blue',
            padding: '7px 13px',
            width: 250,
            tip: true
        }
    });
    $j('#j_password').qtip({
        position: {
            corner: {
                target: 'topMiddle',
                tooltip: 'bottomMiddle'
            }
        },
        content: "请在此输入您的密码!",
        style: {
            name: 'blue',
            padding: '7px 13px',
            width: 250,
            tip: true
        }
    });
    $j('#j_captcha_response').qtip({
        position: {
            corner: {
                target: 'topMiddle',
                tooltip: 'bottomMiddle'
            }
        },
        content: "请在此输入左边验证码!",
        style: {
            name: 'blue',
            padding: '7px 13px',
            width: 200,
            tip: true
        }
    });
    $j('#j_button_submit').qtip({
        position: {
            corner: {
                target: 'topMiddle',
                tooltip: 'bottomMiddle'
            }
        },
        content: "点击此处提交登录信息!",
        style: {
            name: 'blue',
            padding: '7px 13px',
            width: 250,
            tip: true
        }
    });
});

?

?这里有一个小小的技巧,那就是不让浏览器缓存验证码图片,var realoadRandom = Math.random();在外面设置了

这个变量,做随机变量。

?

function refreshLoadRandom(obj, src){

?? ?realoadRandom = Math.random();

?? ?obj.src = src + "&amp;ran=" + realoadRandom;

}

目的还是清楚缓存的辅助方法。

content: '<img align=\"middle\" style=\"text-align: center; cursor: pointer;\" src=\"' + contextPath + '/jcaptcha\" onclick=\"this.src=\'' + contextPath + '/jcaptcha?now=' +
            realoadRandom +
            '\';refreshLoadRandom(this,\'' +
            contextPath +
            '/jcaptcha?nowa=nk\');\" alt=\"看不清,点击换一张\"/>',
?

?

这个才是真正的生成验证码图片提示框的,src就是servlet地址,onclick是一部调用的关键,采用this.src重新赋值的

形式清楚浏览器的缓存,后面跟着一个无用的参数,名字随便起,之后realoadRandom是改变值了,要是不在此修改src的话,浏览器会缓存下来,所以要改变realoadRandom的,并且在此切换src的地址,保证不被缓存,点击的时候一次是

切换这两个地址,改变其src获取不同的图片。

?

1 楼 nighthawk 2010-08-18  
我说啊,就一个验证码怎么搞的这么复杂
2 楼 笑我痴狂 2010-09-13  
nighthawk 写道
我说啊,就一个验证码怎么搞的这么复杂


同意
3 楼 BestUpon 2010-09-13  
笑我痴狂 写道
nighthawk 写道
我说啊,就一个验证码怎么搞的这么复杂


同意


各有所见:正所谓,同样是饼子,为什么还会有烧饼,不就是饼子么?调味品不一样而已。
4 楼 TESZLX 2010-11-02  
BestUpon 写道
笑我痴狂 写道
nighthawk 写道
我说啊,就一个验证码怎么搞的这么复杂


同意


各有所见:正所谓,同样是饼子,为什么还会有烧饼,不就是饼子么?调味品不一样而已。

5 楼 binge520 2011-05-11  
能不能简单点 挺麻烦的
6 楼 ldsjdy 2011-09-24  
不错,刚好需要用到,参考一下
  相关解决方案