日期:2014-05-17  浏览次数:20859 次

用struts2+javabean写了一个验证码,出现了令人费解的异常!!!!
刷新显示验证码的页面后,在后台发现生成了两次验证码,页面显示的是第一次生成的验证码,用firebug查看,发现传回来的是第二次生成的验证码。非常费解为什么会生成两次验证码!!!!!!!!!!而且页面显示的还不是第二次生成的验证码。
下面是验证码的javabean:
Java code

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[