首先看看效果图:
如上图,点击验证码可以异步的刷新,借助了一个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 + "&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 + "&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获取不同的图片。