java 算数验证码,后台验证不通过?

发布于 2021-12-05 04:17:18 字数 8716 浏览 985 评论 7

前两天一直找算数验证码,后来终于东拼西凑搞出来了,但是后台验证老是返回false?求大神帮忙查看,是什么问题??? 我调试的sessionid都有值的, boolean b验证总是返回false?   在下面代码匹配验证码正确性那出错了,b一直返回false??

public class CaptchaServiceSingleton {
	private static DefaultManageableImageCaptchaService instance=null;
    public static int result;

    /**
     * 单例模式的类用于生成图片
     * @return
     */
    public static ImageCaptchaService getInstance() {
        VerifImage vi= new VerifImage();
        result=vi.getResult();
        if(instance==null){
            instance = new DefaultManageableImageCaptchaService(new FastHashMapCaptchaStore(), vi, 180, 100000, 75000);
        }else{
            instance.setCaptchaEngine(vi);
        }
        return instance;
    }
}


public class ImageCaptchaServlet extends HttpServlet {
    private static final long serialVersionUID = -11L;
    
    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        byte[] b = null;

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            //获取session对象
            HttpSession session=request.getSession();

           //获取本次会话的sessionID
            String captchaId = session.getId();
            //生成图片
            BufferedImage challenge = CaptchaServiceSingleton.getInstance().getImageChallengeForID(captchaId, request.getLocale());

            //将结果保存到session
            session.setAttribute(captchaId,CaptchaServiceSingleton.result);
            ImageIO.write(challenge,"jpg",baos);
            //加密
//            JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(baos);           
//
//            jpegEncoder.encode(challenge);

        } catch (IllegalArgumentException e) {

            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;

        } catch (CaptchaServiceException e) {

            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;

        }

        b = baos.toByteArray();

        //设置相应的参数,用于显示图片
        response.setDateHeader("Expires", 1L);
        response.addHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
        response.setContentType("image/jpeg");
        ServletOutputStream sos = response.getOutputStream();
        sos.write(b);
        sos.flush();
        sos.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

public class VerifImage extends ListImageCaptchaEngine {
	static{
	      System.setProperty("java.awt.headless", "true");
	  }
    private final static String[] noss={"0","1","2","3","4","5","6","7","8","9"};
    // 存放加减乘运算符
    private final static char[] arr = {'+', '-', '×'};
    //汉字加减乘运算符
    private StringBuffer stringBuffer=null;
    private Random random=null;
    private int result;
    public int getResult(){
        return result;
    }
    @Override
    protected void buildInitialFactories() {
        random = new Random();
        stringBuffer=new StringBuffer();
        //获取一个随机boolean
        boolean bool=random.nextBoolean();
        //掉用生成运算模式方法
        this.model(bool);
        int len=stringBuffer.toString().length();
        WordGenerator wgen=new DummyWordGenerator(stringBuffer.toString());
        //设置字体颜色
        RandomRangeColorGenerator cgen = new RandomRangeColorGenerator(new int[]{0, 150}, new int[]{0, 150}, new int[]{0, 150});
        // 文字显示的个数
        TextPaster textPaster = new RandomTextPaster(len, len, cgen, true);
        //设置图片背景颜色
        ColorGenerator colorGenerator = new RandomRangeColorGenerator(new int[]{200, 200}, new int[]{200, 200}, new int[]{200, 200});
        // 图片的大小
        BackgroundGenerator backgroundGenerator = new FunkyBackgroundGenerator(130, 40,colorGenerator);
        // 字体格式
        Font[] fontsList = new Font[]{new Font("宋体", 0, 10)};
        // 文字的大小
        FontGenerator fontGenerator = new RandomFontGenerator(20, 20, fontsList);
        //将文字写入到图片中
        WordToImage wordToImage = new ComposedWordToImage(fontGenerator, backgroundGenerator, textPaster);
        this.addFactory(new GimpyFactory(wgen, wordToImage));

    }
    private void model(boolean bool){
        // 生成随机整数num1
        int num1 = getRandomNum();
        // 生成随机整数num2
        int num2 = getRandomNum();
        //随机产生运算方式
        int operate = random.nextInt(3);
        switch (operate) {
            case 0:
                this.result = num1 + num2;
                break;
            case 1:
                this.result = num1 - num2;
                break;
            case 2:
                this.result = num1 * num2;
                break;
        }
        try{
            //随机生成运算表达试
            if(bool){
                this.getRes(operate,num1,num2);
            }else{
                int r=random.nextInt(3);
                stringBuffer.append(getNos(r,num1)+" ");

                r=random.nextInt(2);
                stringBuffer.append(getOperate(r,operate)+" ");

                r=random.nextInt(3);
                stringBuffer.append(getNos(r,num2));
                stringBuffer.append(" = ?");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    //生成运算表达试
    private void getRes(int operate,int num1,int num2){
        int r=random.nextInt(2);
        switch (r){
            case 0:
                r=random.nextInt(3);
                stringBuffer.append(getNos(r,num1)+" ");

                r=random.nextInt(2);
                stringBuffer.append(getOperate(r,operate)+" ");
                stringBuffer.append("?");

                stringBuffer.append(" = "+this.result);
                this.result=num2;
                break;
            case 1:
            	stringBuffer.append("? ");
                r=random.nextInt(2);
                stringBuffer.append(getOperate(r,operate)+" ");

                r=random.nextInt(3);
                stringBuffer.append(getNos(r,num2));

                stringBuffer.append(" = "+this.result);
                this.result=num1;
                break;
        }
    }
    //获取运算数字
    private String getNos(int random,int num) {
        switch (random){
            case 0:
                return noss[num];
            case 1:
                return noss[num];
            case 2:
                return noss[num];
        }
        return null;
    }
    //获取运算符
    private String getOperate(int random,int num){
        switch (random){
            case 0:
                return String.valueOf(arr[num]);
            case 1:
                return String.valueOf(arr[num]);
        }
        return null;
    }
    //获取0~9随机数
    private int getRandomNum(){
        int num = random.nextInt(10);
        while (num == 0) {
            num = random.nextInt(10);
        }
        return num;
    }
}

public class CspUsernamePasswordAuthenticationFilter extends
		UsernamePasswordAuthenticationFilter {
	// 验证码字段  
    private String validateCodeParameter = "validateCode";  
  
    // 匹对验证码的正确性  
    public void checkValidateCode(HttpServletRequest request) {  
  
        String jcaptchaCode = obtainValidateCodeParameter(request);  
        if (null == jcaptchaCode)  
            throw new AuthenticationServiceException("验证码超时,请重新获取!");  
        boolean b = CaptchaServiceSingleton.getInstance().validateResponseForID(request.getSession().getId(), jcaptchaCode);  
        if (!b)  
            throw new AuthenticationServiceException("验证码不正确,请重新输入!");  
    }  
  
    public String obtainValidateCodeParameter(HttpServletRequest request) {  
        Object obj = request.getParameter(getValidateCodeParameter());  
        return null == obj ? "" : obj.toString().trim();  
    }  
    @Override  
    protected String obtainUsername(HttpServletRequest request) {  
        Object obj = request.getParameter(getUsernameParameter());  
        return null == obj ? "" : obj.toString().trim();  
    }  
  
    @Override  
    protected String obtainPassword(HttpServletRequest request) {  
        Object obj = request.getParameter(getPasswordParameter());  
        return null == obj ? "" : obj.toString().trim();  
    }  
  
    public String getValidateCodeParameter() {  
        return validateCodeParameter;  
    }  
  
    public void setValidateCodeParameter(String validateCodeParameter) {  
        this.validateCodeParameter = validateCodeParameter;  
    }  
  

}


 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

飘过的浮云 2021-12-05 11:13:11

那该怎么改?求教

绝影如岚 2021-12-05 11:09:58

回复
多个请求公用同一个全局变量,并发肯定会有问题。不要使用全局变量传递返回结果。生成图片并返回的方法,将这个结果一同返回。

挽清梦 2021-12-05 11:08:31

回复
每个链接是否共用这一个单例,如果是,那就会共用这一个属性,当然就会有问题

晚风撩人 2021-12-05 10:41:58
CaptchaServiceSingleton.result

这个地方使用了全局变量,并发会出错。

 

虐人心 2021-12-05 08:55:03

我感觉你还是debug跟踪一下你的那个设置sessionid关联验证码和获取验证的方法。

醉酒的小男人 2021-12-05 08:01:42

回复
@云遮七月 : 我跟踪了,跟踪一天了,就是没找出来为什么我调用CaptchaServiceSingleton.getInstance() .validateResponseForID(request.getSession().getId(),jcaptchaCode); 方法时总是返回false,都纳闷了,难道就我一个人遇到这个问题了

把回忆走一遍 2021-12-05 06:31:06

你在生成验证码的地方将结果放在session中,在验证的时候又去生成图片的地方去验证。这两个地方有不一样吧。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文