如何获取Captcha的当前会话值?

时间:2013-11-21 11:26:13

标签: java javascript html jsp

请帮助我!我被卡住了!

我正在尝试比较在textfield中插入的值和Captcha(图片)中显示的值,如果匹配则会显示警告('是!')否则警告('否!')即可。但是当我试图获得Captcha(request.getSession().getAttribute("captcha"))的会话值时,它获得了它的先前值!

如何确保Catcha的价值与用户在图片上看到的相同?

Captcha.jsp:

<%@ page import="java.util.*"%>
<%@ page import="java.io.*"%>
<%@ page import="javax.servlet.*"%>
<%@ page import="javax.servlet.http.*"%>
<%@ page import="java.awt.*"%>
<%@ page import="java.awt.image.*"%>
<%@ page import="javax.imageio.*"%>
<%@ page import="java.awt.geom.*"%>
<%
    String imageFormat = "jpg";
    response.setContentType("image/" + imageFormat);

    try {
        // you can pass in fontSize, width, height via the request

        Color backgroundColor = Color.red;
        Color borderColor = Color.black;
        Color textColor = Color.white;
        Color circleColor = new Color(160, 160, 160);
        Font textFont = new Font("Arial", Font.PLAIN, paramInt(request,
                "fontSize", 24));
        int charsToPrint = 6;
        int width = paramInt(request, "width", 150);
        int height = paramInt(request, "height", 80);
        int circlesToDraw = 6;
        float horizMargin = 20.0f;
        float imageQuality = 0.95f; // max is 1.0 (this is for jpeg)
        double rotationRange = 0.7; // this is radians
        BufferedImage bufferedImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();

        g.setColor(backgroundColor);
        g.fillRect(0, 0, width, height);

        // lets make some noisey circles
        g.setColor(circleColor);
        for (int i = 0; i < circlesToDraw; i++) {
            int circleRadius = (int) (Math.random() * height / 2.0);
            int circleX = (int) (Math.random() * width - circleRadius);
            int circleY = (int) (Math.random() * height - circleRadius);
            g.drawOval(circleX, circleY, circleRadius * 2,
                    circleRadius * 2);
        }

        g.setColor(textColor);
        g.setFont(textFont);

        FontMetrics fontMetrics = g.getFontMetrics();
        int maxAdvance = fontMetrics.getMaxAdvance();
        int fontHeight = fontMetrics.getHeight();

        // i removed 1 and l and i because there are confusing to users...
        // Z, z, and N also get confusing when rotated
        // 0, O, and o are also confusing...
        // lowercase G looks a lot like a 9 so i killed it
        // this should ideally be done for every language...
        // i like controlling the characters though because it helps prevent confusion
        String elegibleChars = "ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789";
        char[] chars = elegibleChars.toCharArray();

        float spaceForLetters = -horizMargin * 2 + width;
        float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);

        AffineTransform transform = g.getTransform();

        StringBuffer finalString = new StringBuffer();

        for (int i = 0; i < charsToPrint; i++) {
            double randomValue = Math.random();
            int randomIndex = (int) Math.round(randomValue * (chars.length - 1));
            char characterToShow = chars[randomIndex];
            finalString.append(characterToShow);

            // this is a separate canvas used for the character so that
            // we can rotate it independently
            int charImageWidth = maxAdvance * 2;
            int charImageHeight = fontHeight * 2;
            int charWidth = fontMetrics.charWidth(characterToShow);
            int charDim = Math.max(maxAdvance, fontHeight);
            int halfCharDim = (int) (charDim / 2);

            BufferedImage charImage = new BufferedImage(charDim,
                    charDim, BufferedImage.TYPE_INT_ARGB);
            Graphics2D charGraphics = charImage.createGraphics();
            charGraphics.translate(halfCharDim, halfCharDim);
            double angle = (Math.random() - 0.5) * rotationRange;
            charGraphics.transform(AffineTransform
                    .getRotateInstance(angle));
            charGraphics.translate(-halfCharDim, -halfCharDim);
            charGraphics.setColor(textColor);
            charGraphics.setFont(textFont);

            int charX = (int) (0.5 * charDim - 0.5 * charWidth);
            charGraphics
                    .drawString(
                            "" + characterToShow,
                            charX,
                            (int) ((charDim - fontMetrics.getAscent()) / 2 + fontMetrics
                                    .getAscent()));

            float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
            int y = (int) ((height - charDim) / 2);
            //System.out.println("x=" + x + " height=" + height + " charDim=" + charDim + " y=" + y + " advance=" + maxAdvance + " fontHeight=" + fontHeight + " ascent=" + fontMetrics.getAscent());
            g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);

            charGraphics.dispose();
        }

        // let's do the border
        g.setColor(borderColor);
        g.drawRect(0, 0, width - 1, height - 1);

        //Write the image as a jpg
        Iterator iter = ImageIO
                .getImageWritersByFormatName(imageFormat);
        if (iter.hasNext()) {
            ImageWriter writer = (ImageWriter) iter.next();
            ImageWriteParam iwp = writer.getDefaultWriteParam();
            if (imageFormat.equalsIgnoreCase("jpg")
                    || imageFormat.equalsIgnoreCase("jpeg")) {
                iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                iwp.setCompressionQuality(imageQuality);
            }
            writer.setOutput(ImageIO.createImageOutputStream(response.getOutputStream()));
            IIOImage imageIO = new IIOImage(bufferedImage, null, null);
            writer.write(null, imageIO, iwp);
        } else {
            throw new RuntimeException("no encoder found for jsp");
        }

        // set session
        request.getSession().setAttribute("captcha", finalString.toString()); 

System.out.println("Captcha.jsp: "+request.getSession().getAttribute("captcha"));//for console output

        out.clear();
        out = pageContext.pushBody();


        g.dispose();
    } catch (IOException ioe) {
        throw new RuntimeException("Unable to build image", ioe);
    }
%>

<%!public static String paramString(HttpServletRequest request,
        String paramName, String defaultString) {
    return request.getParameter(paramName) != null ? request
            .getParameter(paramName) : defaultString;
}

public static int paramInt(HttpServletRequest request, String paramName,
        int defaultInt) {
    return request.getParameter(paramName) != null ? Integer
            .parseInt(request.getParameter(paramName)) : defaultInt;
}%>

设置我正在使用的sesion - request.getSession().setAttribute("captcha", finalString.toString());

ValidateCapture.jsp:

<html>
<head>

<script type="text/javascript"> 

function ValidateCaptcha(){
    <%String captcha=(String)request.getSession().getAttribute("captcha");%>
    var answer = document.getElementById("answer").value;
    var captcha = '<%=captcha%>';

    if(answer==captcha){
        alert('Yes');
    }
    else{
        alert('No');
    }
}
</script>


</head>
<body>
    <img src="Captcha.jsp"/>
    <input id="answer" type="text">
    <input type="button" value="Submit" onclick="ValidateCaptcha();">
    <%System.out.println("ValidateCapture.jsp: "+request.getSession().getAttribute("captcha"));%> <!--for console output-->
</body>

要使用我正在使用的会话 - request.getSession().getAttribute("captcha");

控制台输出:

enter image description here

1 个答案:

答案 0 :(得分:0)

我看到了代码。特别是关于设定会议。我以为你不应该设置属性值。首先,当tomcat配置文件中浏览器关闭或无操作时间超过30分钟时,会话无效。但是,如果您没有关闭浏览器,则会获得与之前值相同的验证码。所以,我们可以这样做,请遵循以下代码:request.setAttribute("captcha", finalString.toString()); //设置值和request.getAttribute("captcha");//get value


像这样。当我们点击图片时,我们会得到不同的验证码值。请求对象也发生了变化。为什么这样?因为当“请求”服务器和服务器稍后响应时,请求对象无效。下一个请求将产生新的请求对象。就这样,祝你好运。