刷新显示验证码的页面后,在后台发现生成了两次验证码,页面显示的是第一次生成的验证码,用firebug查看,发现传回来的是第二次生成的验证码。非常费解为什么会生成两次验证码!!!!!!!!!!而且页面显示的还不是第二次生成的验证码。
下面是验证码的javabean:public final class Captcha { private String imgType = "png";
private String sessionWord = "captchaWord";
private int height = 20;
private int width = 130; public Captcha() { } /**
 * 检查给出的验证码是否和session中的一致
 * 
 * @param session
 * @param word
 * @return
 */
@SuppressWarnings("rawtypes")
public boolean checkWord(Map session, String word) {
if (session == null || word == null)
return false;
String given = this.encryptsWord(word);
Object o = session.get(this.sessionWord);
String recorded = (o != null) ? (String) o : "";
if (recorded.equals(given))
return true;
return false;
} /**
 * 生成图片输出到输出流,并将加密后的验证码写到session
 * 
 * @param session
 * @param os
 */
@SuppressWarnings("rawtypes")
public void generateImage(Map session, OutputStream os) {
if (session == null || os == null)
throw new ExceptionInInitializerError("OutputStream required!");
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(new Color(0xDCDCDC));
g.fillRect(0, 0, width, height);
g.setColor(Color.black);
g.drawRect(0, 0, width - 1, height - 1);
String strEnsure = this.generateWord();
System.out.println("加密前的验证码是:"+strEnsure);
this.recordWord(session, strEnsure);
g.setColor(Color.black);
g.setFont(new Font("Atlantic Inline", Font.PLAIN, 18));
String str = strEnsure.substring(0, 1);
g.drawString(str, 38, 17);
str = strEnsure.substring(1, 2);
g.drawString(str, 50, 15);
str = strEnsure.substring(2, 3);
g.drawString(str, 65, 18);
str = strEnsure.substring(3, 4);
g.drawString(str, 75, 15);
Random random = new Random();
for (int i = 0; i < 150; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
g.drawOval(x, y, 1, 1);
}
g.dispose();
try {
ImageIO.write(image, this.imgType, os);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}

} /**
 * 对需要记录的串进行加密
 * 
 * @param word
 *            原始字符串
 * @return
 */
private String encryptsWord(String word) {
if (word == null)
return null;
String result = null;
try {
result = MyMD5.MD5encode(word);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return result;
} /**
 * 将验证码保存到session
 * 
 * @param word
 * @param session
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
private void recordWord(Map session, String word) {
if (session == null)
throw new RuntimeException("method recordWord require session");
session.put(this.sessionWord, this.encryptsWord(word));
} /**
 * 生成4位随机的验证码
 * 
 * @return
 */
@SuppressWarnings("rawtypes")
private String generateWord() {
String[] beforeShuffle = new String[] { "2", "3", "4", "5", "6", "7",
"8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z" };
List list = Arrays.asList(beforeShuffle);
Collections.shuffle(list);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i));
}
return sb.toString().substring(5, 9);
}
}下面是生成验证码图片的struts2的action:public class GetCaptcha extends ActionSupport implements SessionAware { @SuppressWarnings("rawtypes")
private Map session; @SuppressWarnings("rawtypes")
public void setSession(Map session) {
this.session = session; } @Override
public String execute() throws Exception {
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("image/png");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
ServletOutputStream outputStream = response.getOutputStream();
Captcha captcha = new Captcha();
captcha.generateImage(this.session, outputStream);
return null;
}}下面是html页面代码:
<img src="getCaptcha.action" id="captchaId" width="145" height="20" alt="CAPTCHA" border="1" onclick="getCaptcha()" style="cursor: pointer;" title="看不清?点击更换另一个验证码。" />
  function getCaptcha(){
    document.getElementById("captchaId").src="getCaptcha.action?K="+Math.random();
  }