欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Action验证码误区

程序员文章站 2022-05-13 15:54:17
...
Action图形验证码,代码来自互联网。
public String execute() throws Exception {
		 try {   
		        int width = 50;   
		        int height = 18;   
		        // 取得一个4位随机字母数字字符串   
		        String s = RandomStringUtils.random(4, true, true);   
		        // 保存入session,用于与用户的输入进行比较.   
		        // 注意比较完之后清除session.   
		        ActionContext.getContext().getSession().put("validateCode", s);   
		        response.setContentType("images/jpeg");   
		        response.setHeader("Pragma", "No-cache");   
		        response.setHeader("Cache-Control", "no-cache");   
		        response.setDateHeader("Expires", 0);   
		        ServletOutputStream out = response.getOutputStream();   
		        BufferedImage image = new BufferedImage(width, height,   
		            BufferedImage.TYPE_INT_RGB);   
		        Graphics g = image.getGraphics();   
		        // 设定背景色   
		        g.setColor(getRandColor(200, 250));   
		        g.fillRect(0, 0, width, height);   
		        // 设定字体   
		        Font mFont = new Font("Times New Roman", Font.BOLD, 18);// 设置字体   
		        g.setFont(mFont);   
		        // 画边框   
		        // g.setColor(Color.BLACK);   
		        // g.drawRect(0, 0, width - 1, height - 1);   
		        // 随机产生干扰线,使图象中的认证码不易被其它程序探测到   
		        g.setColor(getRandColor(160, 200));   
		        // 生成随机类   
		        Random random = new Random();   
		        for (int i = 0; i < 155; i++) {   
		          int x2 = random.nextInt(width);   
		          int y2 = random.nextInt(height);   
		          int x3 = random.nextInt(12);   
		          int y3 = random.nextInt(12);   
		          g.drawLine(x2, y2, x2 + x3, y2 + y3);   
		        }   
		        // 将认证码显示到图象中   
		        g.setColor(new Color(20 + random.nextInt(110), 20 + random   
		            .nextInt(110), 20 + random.nextInt(110)));   
		        g.drawString(s, 2, 16);   
		        // 图象生效   
		        g.dispose();   
		        // 输出图象到页面   
		        ImageIO.write((BufferedImage) image, "JPEG", out);   
		        out.close();   
		        
		        
		        System.out.println("验证码:"+ActionContext.getContext().getSession().get("validateCode"));
		        
		        
		      } 
		 	  catch (Exception e) {   
		        e.printStackTrace();   
		      }   
		      return null;   
		    }
	
	 		// 给定范围获得随机颜色
		    private Color getRandColor(int fc, int bc) {   
		      Random random = new Random();   
		      if (fc > 255)   
		        fc = 255;   
		      if (bc > 255)   
		        bc = 255;   
		      int r = fc + random.nextInt(bc - fc);   
		      int g = fc + random.nextInt(bc - fc);   
		      int b = fc + random.nextInt(bc - fc);   
		      return new Color(r, g, b);   
		  }  

 界面

<img src="memory/validateCode.action" style="cursor:pointer;"/>
	    			<input id="validationCode" type="text" value="<%=session.getAttribute("validateCode")%>"></input>

 

js代码

var validationCode=document.getElementById("validationCode");
	alert(validationCode.value);

 

误区,一般会认为jsp页面按顺序执行,先加载图片,执行了execute方法,此时验证码已经存入session,再将验证码放入hidden隐藏域……

实际上jsp也页面的处理过程如下:

1.首先将jsp页面生成一个servlet源程序文件

2.然后调用java编译器将这个文件处理成.class文件

3.并由Servlet引擎来装载并执行这个.class文件

 

上面的页面执行过程如下:

1.该jsp页面生成Servlet源程序文件

2.该源程序被处理成.class文件

3.Servlet引擎装载处理该.class文件,此时session.getAttribute("validateCode")已经被执行了

4.将处理结果发送给客户端浏览器

5.浏览器遇到img标签执行execute方法

 

所以实际上以上方法第一次隐藏域中的值为null,以后每次的值都是前一次的值