你的位置:首页 > Java教程

[Java教程]extjs ajax java简单精美验证码实现 有图


前端:利用ExtJs的autoEl功能加载图片。

 1   var imgCheckValid = new Ext.create('Ext.Component',{  2     width: 70, //图片宽度  3     height: 45, //图片高度  4     margin:'5', 5     id:"imd_imgCheckValid", 6     autoEl: {  7       tag: 'img',  //指定为img标签  8       src: 'Code/genCodeImg.do?'  //指定url路径  9     },10     listeners: {11       render: function(component){12          component.getEl().on('click', function(e){13           this.dom.src = 'Code/genCodeImg.do?'+(new Date().getTime()); // autoEl不会自动加载,只有设置了不同的src才会加载14         });  15        }16     }17   });

小编心得:autoEl会自动加载,要实现点击验证码刷新,登录失败刷新,方法是给请求的url加上时间戳。所以刷新验证码只要在需要刷新的时候重新设置加上时间戳的src即可。

疑问解答:为什么只是给了src一个路径,并没有给图片地址,页面能显示图片呢?

目前不是很清楚:猜想它是根据给的链接,自动从response中获得二进制资源。明确的是我会向response中写入流

后台:struts,spring配置

struts:

1   <!-- 客户端 -->2   <package name="Code" extends="json" namespace="/Code">3     <action name="genCodeImg" class="codeAction" method="genCodeImg">4       <result name="success" type="json">5         <param name="root">responseJson</param>6       </result>7     </action>8   </package>

 spring:

1 <!-- 验证码生成器--> 2 <bean id="codeAction" 3 scope="prototype"></bean> 

后台:

 1 import java.awt.Color; 2 import java.awt.Font; 3 import java.awt.Graphics; 4 import java.awt.image.BufferedImage; 5 import java.util.Map; 6 import java.util.Random; 7  8 import javax.imageio.ImageIO; 9 import javax.servlet.ServletOutputStream; 10 import javax.servlet.http.HttpServletResponse; 11  12 import org.apache.struts2.ServletActionContext; 13  14 import com.common.core.st2.action.BaseAction; 15 import com.opensymphony.xwork2.ActionContext; 16 import com.sinsche.i.action.ICodeAction; 17  18 public class CodeAction extends BaseAction implements ICodeAction { 19   /** 20    *  21   */ 22   private static final long serialVersionUID = 6865491407475710154L; 23   private boolean success; 24   private String message; 25   // 图片的宽度。 26   private int width = 70; 27   // 图片的高度。 28   private int height = 45; 29   // 验证码字符个数 30   private int codeCount = 4; 31   // 验证码干扰线数 32   private int lineCount = 20; 33   // 验证码图片Buffer 34   private BufferedImage buffImg = null; 35   Random random = new Random(); 36   public String genCodeImg() throws Exception { 37     HttpServletResponse resp = ServletActionContext.getResponse(); 38     int fontWidth = width / codeCount;// 字体的宽度 39     int fontHeight = height - 5;// 字体的高度 40     int codeY = height - 8; 41  42     // 图像buffer 43     buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 44     Graphics g = buffImg.getGraphics(); 45     // Graphics2D g = buffImg.createGraphics(); 46     // 设置背景色 47     g.setColor(getRandColor(200, 250)); 48     g.fillRect(0, 0, width, height); 49  50     // 设置字体 51     // Font font1 = getFont(fontHeight); 52     Font font = new Font("Fixedsys", Font.BOLD, fontHeight); 53     g.setFont(font); 54  55     // 设置干扰线 56     for (int i = 0; i < lineCount; i++) { 57       int xs = random.nextInt(width); 58       int ys = random.nextInt(height); 59       int xe = xs + random.nextInt(width); 60       int ye = ys + random.nextInt(height); 61 //      g.setColor(getRandColor(1, 255)); 62       shear(g,1,20,getRandColor(1, 255)); 63       g.drawLine(xs, ys, xe, ye); 64     } 65  66     // 添加噪点 67     float yawpRate = 0.01f;// 噪声率 68     int area = (int) (yawpRate * width * height); 69     for (int i = 0; i < area; i++) { 70       int x = random.nextInt(width); 71       int y = random.nextInt(height); 72  73       buffImg.setRGB(x, y, random.nextInt(255)); 74     } 75  76     String str1 = randomStr(codeCount);// 得到随机字符 77     for (int i = 0; i < codeCount; i++) { 78       String strRand = str1.substring(i, i + 1); 79       g.setColor(getRandColor(1, 255)); 80       // g.drawString(a,x,y); 81       // a为要画出来的东西,x和y表示要画的东西最左侧字符的基线位于此图形上下文坐标系的 (x, y) 位置处 82  83       g.drawString(strRand, i * fontWidth + 3, codeY); 84     } 85  86     // 将四位数字的验证码保存到Session中。 87     Map<String, Object> map = ActionContext.getContext().getSession(); 88     System.out.print(str1); 89     map.put("code", str1.toString()); 90     // 禁止图像缓存。 91     resp.setHeader("Pragma", "no-cache"); 92     resp.setHeader("Cache-Control", "no-cache"); 93     resp.setDateHeader("Expires", 0); 94  95     resp.setContentType("image/jpeg"); 96  97     // 将图像输出到Servlet输出流中。 98     ServletOutputStream sos = resp.getOutputStream(); 99     ImageIO.write(buffImg, "jpeg", sos);100     sos.close();101 102     return null;103   }104 105   // 得到随机字符106   private String randomStr(int n) {107     String str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";108     String str2 = "";109     int len = str1.length() - 1;110     double r;111     for (int i = 0; i < n; i++) {112       r = (Math.random()) * len;113       str2 = str2 + str1.charAt((int) r);114     }115     return str2;116   }117 118   // 得到随机颜色119   private Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色120     if (fc > 255)121       fc = 255;122     if (bc > 255)123       bc = 255;124     int r = fc + random.nextInt(bc - fc);125     int g = fc + random.nextInt(bc - fc);126     int b = fc + random.nextInt(bc - fc);127     return new Color(r, g, b);128   }129 130 //  /**131 //   * 产生随机字体132 //   */133 //  private Font getFont(int size) {134 //    Font font[] = new Font[5];135 //    font[0] = new Font("Ravie", Font.PLAIN, size);136 //    font[1] = new Font("Antique Olive Compact", Font.PLAIN, size);137 //    font[2] = new Font("Fixedsys", Font.PLAIN, size);138 //    font[3] = new Font("Wide Latin", Font.PLAIN, size);139 //    font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, size);140 //    return font[random.nextInt(5)];141 //  }142 143   // 扭曲方法144   private void shear(Graphics g, int w1, int h1, Color color) {145     shearX(g, w1, h1, color);146     shearY(g, w1, h1, color);147   }148 149   private void shearX(Graphics g, int w1, int h1, Color color) {150 151     int period = random.nextInt(2);152 153     boolean borderGap = true;154     int frames = 1;155     int phase = random.nextInt(2);156 157     for (int i = 0; i < h1; i++) {158       double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);159       g.copyArea(0, i, w1, 1, (int) d, 0);160       if (borderGap) {161         g.setColor(color);162         g.drawLine((int) d, i, 0, i);163         g.drawLine((int) d + w1, i, w1, i);164       }165     }166 167   }168 169   private void shearY(Graphics g, int w1, int h1, Color color) {170 171     int period = random.nextInt(40) + 10; // 50;172 173     boolean borderGap = true;174     int frames = 20;175     int phase = 7;176     for (int i = 0; i < w1; i++) {177       double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);178       g.copyArea(i, 0, 1, h1, 0, (int) d);179       if (borderGap) {180         g.setColor(color);181         g.drawLine(i, (int) d, i, 0);182         g.drawLine(i, (int) d + h1, i, h1);183       }184 185     }186 187   }188 189   public BufferedImage getBuffImg() {190     return buffImg;191   }192   @Override193   public String list() throws Exception {194     return null;195   }196 197   @Override198   public String create() throws Exception {199     return null;200   }201 202   @Override203   public String update() throws Exception {204     return null;205   }206 207   @Override208   public String delete() throws Exception {209     return null;210   }211 212   @Override213   public String listByPage() throws Exception {214     return null;215   }216 217   public boolean isSuccess() {218     return success;219   }220 221   public void setSuccess(boolean success) {222     this.success = success;223   }224 225   public String getMessage() {226     return message;227   }228 229   public void setMessage(String message) {230     this.message = message;231   }232 233 }

效果: