关于如何在Struts下使用jsp图片验证码,请参考另外一篇文章《jsp图片验证码》。其原理就是随机生成4位验证码,将其写入Session,同时生成图片显示出来。这样就出问题了。如果同时打开多个带验证码页面,那么只有最后的页面验证码会通过验证,其他的均提示验证码错误。

其实这个问题当初添加验证码功能的时候就知道会有,但是一直没改,因为很少有人打开多个登录页面,就算是出错了刷新一次就能解决。最近负责项目的师兄盯住这个问题了,所以不得不改改。

这个错误的关键代码在于:

request.getSession().setAttribute(“checkcode”,sRand);

也就是说每次生成验证码都存在Session的checkcode变量里。这样每次生成的验证码都会覆盖上次的值。

网上有许多解决方案,其中一种是给验证码加时间戳。

在将验证码存入Session时使用以下代码:

String timestamp=(String) request.getQueryString();//我这里就一个参数
request.getSession().setAttribute(“checkcode”+timestamp,sRand);

其实原理很简单,就是加入时间戳,把存入Session的变量区别开来。

使用的时候在表单里加入:

<input id=”timestamp” type=”hidden” name=”timestamp” value=”">

同时写一个图片的刷新脚本

function loadimage(){
var timestamp=(new Date()).valueOf(); //timestamp.
document.getElementById(“randImage”).src = “<%=request.getContextPath()%>/image.jsp?”+timestamp;
document.getElementById(“timestamp”).value = timestamp;
}

服务器端直接在form的validate()里使用如下代码取出checkcode即可。

String checkcode= (String) request.getSession().getAttribute(“checkcode”+timestamp);

用完记得顺手清理session:

request.getSession().removeAttribute(“checkcode”+timestamp);

参考链接:http://blog.kongxz.com/2010/01/solution-to-verifying-code-in-multiple-instances/

© 2009 - 2018 冰河的博客