js代码
<script language="javascript" type="text/javascript">
      function reloadImage(imgurl){
          var getp_w_picpathcode=document.getElementById("codeimg");
          getp_w_picpathcode.src= imgurl + "?id=" + Math.random();
      }
  </script>
jsp调用js、strut中的rand.action 代码是我自己编写的,如果copy 特别要注意路径问题
<td height="35" width="20%">                                         <span class="login_txt STYLE1">验证码:</span>                    </td>      <td height="35" colspan="2" class="top_hui_text">                  <input type="text" class="wenbenkuang" id="code" name="code" maxlength="4" size="20">
  <img border="0" id="codeimg" name="codeimg" src="../rand.action">
 <a href="javascript:reloadImage('../rand.action')"><font color="red">看不清</font></a><br>
 </td>
接下来就是rand.action
package com.hz.bbs.action;

import java.io.ByteArrayInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.hz.bbs.util.RandomNumUtil;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class RandomAction extends ActionSupport{ 
    private ByteArrayInputStream inputStream; 
    public String execute() throws Exception{ 
       
        RandomNumUtil rdnu=RandomNumUtil.Instance(); 
       this.setInputStream(rdnu.getImage());//取得带有随机字符串的图片 
       String str = rdnu.getString().toString();
       HttpServletRequest request = ServletActionContext.getRequest();       
         HttpSession session = request.getSession();
         session.setAttribute("randoms", str);//取得随机字符串放入HttpSession
        return SUCCESS; 
    } 
    public void setInputStream(ByteArrayInputStream inputStream) { 
        this.inputStream = inputStream; 
    } 
   public ByteArrayInputStream getInputStream() { 
        return inputStream; 
    }
}

大家一定会觉得 那么生产验证码的图片 写在那里呢?别急,下面就是,我也是在网上copy的 只是拿来改改了
package com.hz.bbs.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.p_w_picpath.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import javax.p_w_picpathio.ImageIO;
import javax.p_w_picpathio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
public class RandomNumUtil { 
    private ByteArrayInputStream p_w_picpath;//图像 
    private String str;//验证码 
    //验证码序列。
    private static final char[] randomSequence = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
        'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y', 'Z', '0','1', '2', '3', '4', '5', '6',
        '7','8', '9' };
     
   private RandomNumUtil(){ 
        init();//初始化属性 
    } 
    
    public static RandomNumUtil Instance(){ 
        return new RandomNumUtil(); 
   } 
    
    public ByteArrayInputStream getImage(){ 
       return this.p_w_picpath; 
   } 
    
    public String getString(){ 
        return this.str; 
    } 
     
    private void init() { 
        //       在内存中创建图象 
        int width=60, height=20; 
        BufferedImage p_w_picpath = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
        //       获取图形上下文 
        Graphics g = p_w_picpath.getGraphics(); 
        //      生成随机类 
        Random random = new Random(); 
        //       设定背景色 
        g.setColor(getRandColor(200,250)); 
        g.fillRect(0, 0, width, height);
      //创建字体,字体的大小应该根据图片的高度来定。
        Font font = new Font("Times New Roman", Font.PLAIN, height-2);
        //设置字体。
        g.setFont(font);
        //随机产生155条干扰线,使图象中的认证码不易被其它程序探测到 
        g.setColor(getRandColor(160,200)); 
        for (int i=0;i<155;i++ ) 
        { 
         int x = random.nextInt(width); 
         int y = random.nextInt(height); 
                int xl = random.nextInt(12); 
                int yl = random.nextInt(12); 
         g.drawLine(x,y,x+xl, y+yl); 
        } 
        //       取随机产生的认证码(6位数字) 
        String sRand=""; 
        for (int i=0;i<4;i++ ){ 
          int index = random.nextInt(35);
             String rand = String.valueOf(randomSequence[index]);
            sRand +=rand; 
            // 将认证码显示到图象中 
            g.setColor(new Color(20 + random.nextInt(110), 20 + random  
                    .nextInt(110), 20 + random.nextInt(110)));
            //      调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 
            g.drawString(rand, 13 * i + 6, 16);
        
        } 
     
        this.str=sRand;
       
    
        //       图象生效 
        g.dispose(); 
        ByteArrayInputStream input=null; 
        ByteArrayOutputStream output = new ByteArrayOutputStream(); 
        try{ 
            ImageOutputStream p_w_picpathOut = ImageIO.createImageOutputStream(output); 
            ImageIO.write(p_w_picpath, "JPEG", p_w_picpathOut); 
            p_w_picpathOut.close(); 
            input = new ByteArrayInputStream(output.toByteArray()); 
        }catch(Exception e){ 
            System.out.println("验证码图片产生出现错误:"+ e.toString()); 
        } 
         
        this.p_w_picpath=input;
    } 
    
    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); 
   } 
 
}
最后一步,就是配置strut.xml了
 <action name="rand" class="com.hz.bbs.action.RandomAction">
   <result type="stream">
    <param name="contentType">p_w_picpath/jpeg</param>
    <param name="inputName">inputStream</param>
   </result>
  </action>
好了 大功告成了 呵呵
图片展示: