1. 前台頁面代碼: 頁面刷新時會自動請求 ${pageContext.request.contextPath}/yanzheng?yz=&time=-1111 這個action
<form name="f" action="" method="post"> 用戶名 : <input id="name" type="text" name="userDTO.userName" /><br> 密 碼 : <input type="password" name="userDTO.passWord" /><br> 驗證碼 : <input type="checkCode" name="userDTO.checkCode" /><br> <img id="myzmDiv" src="${pageContext.request.contextPath}/yanzheng?yz=&time=-1111" onClick="yanZhengMa()" style="width: 80px; height: 40px; border-radius: 4px"> <input type="button" value="submit1" onclick="javascript:document.f.action='user/login';document.f.submit();" /> </form>
<!-- 點擊圖片同樣請求這個 action 進行刷新驗證碼, 需要傳入一個當前時間戳, 避免緩存不更新, 變量yz沒用, 懶得刪 -->
<script type="text/javascript"> function yanZhengMa(){ var yz = ""; $("#myzmDiv").attr("src","${pageContext.request.contextPath}/yanzheng?yz="+yz+"&time="+new Date()); } </script>
2. struts.xml配置文件 不需要result標簽返回, 會自動返回到 請求頁面
<package name="user2" namespace="/" extends="struts-default"> <action name="yanzheng" class="com.test.actions.YanzhengAction" method="yanzhengma" /> </package>
3. yanzhengma 方法實現 會將隨機生成的數字圖片發回到請求頁面, 並且會將生成的數字存儲到 session中, key 和 value 都是生成的隨機數
public String yanzhengma() throws IOException { //"{\"code\":501,\"info\":\"已經在業務中使用,不能刪除\"}"; HttpSession session = ServletActionContext.getRequest().getSession(); String code=""; Captcha cha=new SpecCaptcha(); char[] shu=cha.alphas(); for(int i=0;i<shu.length;i++){ code+=shu[i]+""; } Captcha captcha = new SpecCaptcha(58,28,4,shu);// gif格式動畫驗證碼 HttpServletResponse response = ServletActionContext.getResponse(); ServletOutputStream out = response.getOutputStream(); captcha.out(out); session.setAttribute(code, code); out.flush(); out.close(); return null; }
3-1 > 附屬類: Captcha.java

package com.test.Util; import java.awt.Color; import java.awt.Font; import java.io.OutputStream; public abstract class Captcha { protected Font font = new Font("Verdana", Font.ITALIC|Font.BOLD, 18); // 字體 protected int len = 4; // 驗證碼隨機字符長度 protected int width = 78; // 驗證碼顯示跨度 protected int height = 30; // 驗證碼顯示高度 private String chars = null; // 隨機字符串 protected char[] shu; /** * 生成隨機字符數組 * @return 字符數組 */ public char[] alphas() { char[] cs = new char[len]; for(int i = 0;i<len;i++) { cs[i] = Randoms.alpha(); } chars = new String(cs); return cs; } public Font getFont() { return font; } public void setFont(Font font) { this.font = font; } public int getLen() { return len; } public void setLen(int len) { this.len = len; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public String getChars() { return chars; } public void setChars(String chars) { this.chars = chars; } public char[] getShu() { return shu; } public void setShu(char[] shu) { this.shu = shu; } /** * 給定范圍獲得隨機顏色 * @return Color 隨機顏色 */ protected Color color(int fc, int bc) { if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + Randoms.num(bc - fc); int g = fc + Randoms.num(bc - fc); int b = fc + Randoms.num(bc - fc); return new Color(r, g, b); } /** * 驗證碼輸出,抽象方法,由子類實現 * @param os 輸出流 */ public abstract void out(OutputStream os); /** * 獲取隨機字符串 * @return string */ public String text() { return chars; } }
3-2 > 附屬類: Randoms.java

package com.test.Util; import java.util.Random; /** * <p>隨機工具類</p> * * @author: wuhongjun * @version:1.0 */ public class Randoms { private static final Random RANDOM = new Random(); //定義驗證碼字符.去除了O和I等容易混淆的字母 /* public static final char ALPHA[]={'A','B','C','D','E','F','G','H','G','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z' ,'a','b','c','d','e','f','g','h','i','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z','2','3','4','5','6','7','8','9'}; */ public static final char ALPHA[]={'1','2','3','4','5','6','7','8','9'}; /** * 產生兩個數之間的隨機數 * @param min 小數 * @param max 比min大的數 * @return int 隨機數字 */ public static int num(int min, int max) { return min + RANDOM.nextInt(max - min); } /** * 產生0--num的隨機數,不包括num * @param num 數字 * @return int 隨機數字 */ public static int num(int num) { return RANDOM.nextInt(num); } public static char alpha() { return ALPHA[num(0, ALPHA.length)]; } }
3-3 > 附屬類: SpecCaptcha.java

package com.test.Util; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import javax.imageio.ImageIO; /** * <p>png格式驗證碼</p> * * @author: wuhongjun * @version:1.0 */ public class SpecCaptcha extends Captcha { public SpecCaptcha() { } public SpecCaptcha(int width, int height) { this.width = width; this.height = height; } public SpecCaptcha(int width, int height, int len,char[] shu){ this(width,height); this.len = len; this.shu=shu; } public SpecCaptcha(int width, int height, int len, Font font,char[] shu){ this(width,height,len,shu); this.font = font; } /** * 生成驗證碼 * @throws java.io.IOException IO異常 */ @Override public void out(OutputStream out){ graphicsImage(this.shu, out); } /** * 畫隨機碼圖 * @param strs 文本 * @param out 輸出流 */ private boolean graphicsImage(char[] strs, OutputStream out){ boolean ok = false; try { BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D)bi.getGraphics(); AlphaComposite ac3; Color color ; int len = strs.length; g.setColor(Color.WHITE); g.fillRect(0,0,width,height); // 隨機畫干擾的蛋蛋 for(int i=0;i<15;i++){ color = color(150, 250); g.setColor(color); g.drawOval(Randoms.num(width), Randoms.num(height), 5+Randoms.num(10), 5+Randoms.num(10));// 畫蛋蛋,有蛋的生活才精彩 color = null; } g.setFont(font); int h = height - ((height - font.getSize()) >>1), w = width/len, size = w-font.getSize()+1; /* 畫字符串 */ for(int i=0;i<len;i++) { ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);// 指定透明度 g.setComposite(ac3); color = new Color(20 + Randoms.num(110), 20 + Randoms.num(110), 20 + Randoms.num(110));// 對每個字符都用隨機顏色 g.setColor(color); g.drawString(strs[i]+"",(width-(len-i)*w)+size, h-4); color = null; ac3 = null; } ImageIO.write(bi, "png", out); out.flush(); ok = true; }catch (IOException e){ ok = false; }finally { Streams.close(out); } return ok; } }
3-3 > 附屬類: Streams.java

package com.test.Util; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class Streams { /** * 關閉輸入流 * @param in 輸入流 */ public static void close(InputStream in) { if (in != null) { try { in.close(); } catch (IOException ioex) { // ignore } } } /** * 關閉輸出流 * @param out 輸出流 */ public static void close(OutputStream out) { if (out != null) { try { out.flush(); } catch (IOException ioex) { // ignore } try { out.close(); } catch (IOException ioex) { // ignore } } } }
4. 點擊登錄按鈕后 后台action 校驗 驗證碼是否正確 (userDTO.getCheckCode() 獲取前台頁面傳遞過來的 用戶輸入的驗證碼)
public String login() { HttpSession session2 = ServletActionContext.getRequest().getSession(); String checkCode = (String)session2.getAttribute(userDTO.getCheckCode()); if(checkCode == null) { return "login"; }else { return "welcome"; } }