如何在jsp页面中显示验证码:

 

 
  
  1. 验证码:<img class="yzm_img" align="middle" id="validateImage" src="p_w_picpathCode.action" width="150" height="40" οnclick="this.src='p_w_picpathCode.action?time-'+(new Date()).getTime();"/> 

自动发送p_w_picpathCode.action请求,struts2配置文件如下所写:

 

 
  
  1. <!-- 验证码图片 --> 
  2.         <action name="p_w_picpathCode" class="org.tarena.action.user.ImageAction"> 
  3.             <result name="success" type="stream"> 
  4.                 <param name="inputName">p_w_picpathStream</param> 
  5.                 <param name="bufferSize">2048</param> 
  6.             </result> 
  7.         </action> 

相应的action如下:

 

 
  
  1. public class ImageAction {  
  2.     private InputStream p_w_picpathStream;  
  3.       
  4.     public InputStream getImageStream() {  
  5.         return p_w_picpathStream;  
  6.     }  
  7.  
  8.     public void setImageStream(InputStream p_w_picpathStream) {  
  9.         this.p_w_picpathStream = p_w_picpathStream;  
  10.     }  
  11.  
  12.     public String execute(){  
  13.         Map<String,BufferedImage> map = ImageUtil.getImage();  
  14.         //获取验证图片上的字符,保存到session  
  15.         String key = map.keySet().iterator().next();  
  16.         Map<String,Object> session = ActionContext.getContext().getSession();  
  17.         session.put("code", key);  
  18.         //获取验证图片,以stream方式响应  
  19.         BufferedImage p_w_picpath = map.get(key);  
  20.         ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  21.         JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos);  
  22.         try {  
  23.             jpeg.encode(p_w_picpath);  
  24.             byte[] bts = bos.toByteArray();  
  25.             p_w_picpathStream = new ByteArrayInputStream(bts);  
  26.             return "success";  
  27.         } catch (IOException e) {  
  28.             e.printStackTrace();  
  29.             return "error";  
  30.         }  
  31.     }  

其中ImageUtil类如下:

 

 
  
  1. public final class ImageUtil {  
  2.     private static final String[] chars = { "2""3""4""5""6",  
  3.             "7""8""9""a""b""c""d""e""f""g""h" };  
  4.     private static final int SIZE = 5;  
  5.     private static final int LINES = 20;  
  6.     private static final int WIDTH = 200;  
  7.     private static final int HEIGHT = 100;  
  8.     private static final int FONT_SIZE = 60;  
  9.       
  10.     public static Map<String,BufferedImage> getImage() {  
  11.         StringBuffer sb = new StringBuffer();  
  12.         BufferedImage p_w_picpath = new BufferedImage(WIDTH, HEIGHT,  
  13.                 BufferedImage.TYPE_INT_RGB);  
  14.         Graphics graphic = p_w_picpath.getGraphics();  
  15.         graphic.setColor(Color.LIGHT_GRAY);  
  16.         graphic.fillRect(00, WIDTH, HEIGHT);  
  17.         Random ran = new Random();  
  18.         //������ַ�  
  19.         for(int i=1;i<=SIZE;i++){  
  20.               
  21.             int r = ran.nextInt(chars.length);  
  22.             graphic.setColor(getRandomColor());  
  23.             graphic.setFont(new Font(null,Font.BOLD+Font.ITALIC,FONT_SIZE));  
  24.             graphic.drawString(chars[r],(i-1)*WIDTH/SIZE , HEIGHT/2);  
  25.             sb.append(chars[r]);//���ַ�棬����Session  
  26.         }  
  27.         //��������  
  28.         for(int i=1;i<=LINES;i++){  
  29.             graphic.setColor(getRandomColor());  
  30.             graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), ran.nextInt(WIDTH),ran.nextInt(HEIGHT));  
  31.         }  
  32.         Map<String,BufferedImage> map = new HashMap<String,BufferedImage>();  
  33.         map.put(sb.toString(), p_w_picpath);  
  34.         return map;  
  35.     }  
  36.       
  37.     private static Color getRandomColor(){  
  38.         Random ran = new Random();  
  39.         Color color = new Color(ran.nextInt(256),ran.nextInt(256),ran.nextInt(256));  
  40.         return color;  
  41.     }  
  42. }  

这样action就返回一个流文件到img标签所在的位置,并直接显示出来。

如果想增加“看不清楚换一张的功能”,那就重新再走一遍action,每走一次生成的验证码图片都是随机的。

如何验证填写的验证码是正确的呢?如下:

在页面中使用jquery

 

 
  
  1. $(function(){  
  2.    //验证码校验  
  3.         $("#validateCode").blur(function(){  
  4.             flag.validateCode=false;  
  5.             var txt = $(this).val();  
  6.             if(txt==""){  
  7.                 $("#msg").html("<img src='../p_w_picpaths/right.gif'/>不能为空!");//生成警告图片  
  8.             }else{  
  9.                 $.post(  
  10.                     "valid.action?dt="+new Date().getTime(),  
  11.                     {"code":txt},  
  12.                     function(data){  
  13.                         if(data.ok){  
  14.                             $("#numberInfo").html("<img src='../p_w_picpaths/right.gif'/>验证码正确!");  
  15.                             flag.validateCode=true;  
  16.                         }else{  
  17.                             $("#numberInfo").html("<img src='../p_w_picpaths/wrong.gif'/>验证码不正确!");  
  18.                         }  
  19.                     },  
  20.                     "json" 
  21.                 );  
  22.             }  
  23.         });  
  24.  
  25. }); 

使用了ajax局部刷新,里面的#msg,#numberInfo这都是一些div块的id,这就不用多说了,下面再写一下valid.action所指向的action:

struts2配置文件中如下所写:

 

 
  
  1. <!-- Ajax请求校验验证码 --> 
  2.     <action name="valid" class="org.tarena.action.user.ValidImageAction"> 
  3.         <result name="success" type="json"></result> 
  4.     </action> 

则所指向的action为ValidImageAction:

 

 
  
  1. public class ValidImageAction {  
  2.     private String code = "";  
  3.     private boolean ok = false;  
  4.       
  5.     public boolean isOk() {  
  6.         return ok;  
  7.     }  
  8.  
  9.     public void setOk(boolean ok) {  
  10.         this.ok = ok;  
  11.     }  
  12.  
  13.     public String execute(){  
  14.         Map<String,Object> session = ActionContext.getContext().getSession();  
  15.         //HttpServletRequest request=ServletActionContext.getRequest();  
  16.         String scode = (String)session.get("code");  
  17.         if(code.equals(scode)){  
  18.             ok = true;  
  19.         }else{  
  20.             ok = false;  
  21.         }  
  22.         return "success";  
  23.     }  
  24.  
  25.     @JSON(serialize=false)//防止code值参与json串行化返回  
  26.     public String getCode() {  
  27.         return code;  
  28.     }  
  29.  
  30.     public void setCode(String code) {  
  31.         this.code = code;  
  32.     }  
  33.       

以上使用的是struts2做控制器,如果是servlet或者struts也一样,稍微改动一下