Struts2 验证码图片实例
生活随笔
收集整理的這篇文章主要介紹了
Struts2 验证码图片实例
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
? ? ? ? ? ? ? ? 這周完成一個(gè)小功能,那就是登錄的時(shí)候使用的驗(yàn)證碼,下面講一講步驟。
? ? ? ? ? ? ? ? 第一步:隨機(jī)生成驗(yàn)證碼
package com.dong.framework.tool;import java.util.Arrays;/*** 工具類,生成隨機(jī)驗(yàn)證碼字符串* @version 1.0 2012/08/21* @author dongliyang**/public class SecurityCode {/*** 驗(yàn)證碼難度級(jí)別,Simple只包含數(shù)字,Medium包含數(shù)字和小寫英文,Hard包含數(shù)字和大小寫英文*/public enum SecurityCodeLevel {Simple,Medium,Hard};/*** 產(chǎn)生默認(rèn)驗(yàn)證碼,4位中等難度* @return String 驗(yàn)證碼*/public static String getSecurityCode(){return getSecurityCode(4,SecurityCodeLevel.Medium,false);}/*** 產(chǎn)生長(zhǎng)度和難度任意的驗(yàn)證碼* @param length 長(zhǎng)度* @param level 難度級(jí)別* @param isCanRepeat 是否能夠出現(xiàn)重復(fù)的字符,如果為true,則可能出現(xiàn) 5578這樣包含兩個(gè)5,如果為false,則不可能出現(xiàn)這種情況* @return String 驗(yàn)證碼*/public static String getSecurityCode(int length,SecurityCodeLevel level,boolean isCanRepeat){//隨機(jī)抽取len個(gè)字符int len=length;//字符集合(除去易混淆的數(shù)字0、數(shù)字1、字母l、字母o、字母O)char[] codes={'1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','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','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'};//根據(jù)不同的難度截取字符數(shù)組if(level==SecurityCodeLevel.Simple){codes=Arrays.copyOfRange(codes, 0,9);}else if(level==SecurityCodeLevel.Medium){codes=Arrays.copyOfRange(codes, 0,33);}//字符集合長(zhǎng)度int n=codes.length;//拋出運(yùn)行時(shí)異常if(len>n&&isCanRepeat==false){throw new RuntimeException(String.format("調(diào)用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出現(xiàn)異常," +"當(dāng)isCanRepeat為%3$s時(shí),傳入?yún)?shù)%1$s不能大于%4$s",len,level,isCanRepeat,n));}//存放抽取出來的字符char[] result=new char[len];//判斷能否出現(xiàn)重復(fù)的字符if(isCanRepeat){for(int i=0;i<result.length;i++){//索引 0 and n-1int r=(int)(Math.random()*n);//將result中的第i個(gè)元素設(shè)置為codes[r]存放的數(shù)值result[i]=codes[r];}}else{for(int i=0;i<result.length;i++){//索引 0 and n-1int r=(int)(Math.random()*n);//將result中的第i個(gè)元素設(shè)置為codes[r]存放的數(shù)值result[i]=codes[r];//必須確保不會(huì)再次抽取到那個(gè)字符,因?yàn)樗谐槿〉淖址仨毑幌嗤?/因此,這里用數(shù)組中的最后一個(gè)字符改寫codes[r],并將n減1codes[r]=codes[n-1];n--;}}return String.valueOf(result);}}第二步:生成圖片 package com.dong.framework.tool;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Random;import com.sun.image.codec.jpeg.ImageFormatException;import com.sun.image.codec.jpeg.JPEGCodec;import com.sun.image.codec.jpeg.JPEGImageEncoder;/*** 工具類,生成驗(yàn)證碼圖片* @version 1.0 2012/08/21* @author dongliyang**/public class SecurityImage {/*** 生成驗(yàn)證碼圖片* @param securityCode 驗(yàn)證碼字符* @return BufferedImage 圖片*/public static BufferedImage createImage(String securityCode){//驗(yàn)證碼長(zhǎng)度int codeLength=securityCode.length();//字體大小int fSize = 15;int fWidth = fSize + 1;//圖片寬度int width = codeLength * fWidth + 6 ;//圖片高度int height = fSize * 2 + 1;//圖片BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g=image.createGraphics();//設(shè)置背景色g.setColor(Color.WHITE);//填充背景g.fillRect(0, 0, width, height);//設(shè)置邊框顏色g.setColor(Color.LIGHT_GRAY);//邊框字體樣式g.setFont(new Font("Arial", Font.BOLD, height - 2));//繪制邊框g.drawRect(0, 0, width - 1, height -1);//繪制噪點(diǎn)Random rand = new Random();//設(shè)置噪點(diǎn)顏色g.setColor(Color.LIGHT_GRAY);for(int i = 0;i < codeLength * 6;i++){int x = rand.nextInt(width);int y = rand.nextInt(height);//繪制1*1大小的矩形g.drawRect(x, y, 1, 1);}//繪制驗(yàn)證碼int codeY = height - 10; //設(shè)置字體顏色和樣式g.setColor(new Color(19,148,246));g.setFont(new Font("Georgia", Font.BOLD, fSize));for(int i = 0; i < codeLength;i++){g.drawString(String.valueOf(securityCode.charAt(i)), i * 16 + 5, codeY);}//關(guān)閉資源g.dispose();return image;}/*** 返回驗(yàn)證碼圖片的流格式* @param securityCode 驗(yàn)證碼* @return ByteArrayInputStream 圖片流*/public static ByteArrayInputStream getImageAsInputStream(String securityCode){BufferedImage image = createImage(securityCode);return convertImageToStream(image);}/*** 將BufferedImage轉(zhuǎn)換成ByteArrayInputStream* @param image 圖片* @return ByteArrayInputStream 流*/private static ByteArrayInputStream convertImageToStream(BufferedImage image){ByteArrayInputStream inputStream = null;ByteArrayOutputStream bos = new ByteArrayOutputStream();JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos);try {jpeg.encode(image);byte[] bts = bos.toByteArray();inputStream = new ByteArrayInputStream(bts);} catch (ImageFormatException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return inputStream;}}第三步:驗(yàn)證碼與Struts 2結(jié)合
package com.dong.security.action;import com.opensymphony.xwork2.ActionSupport;import java.io.ByteArrayInputStream;import java.util.Map;import org.apache.struts2.interceptor.SessionAware;import com.dong.framework.tool.SecurityCode;import com.dong.framework.tool.SecurityImage;/*** 提供圖片驗(yàn)證碼* @version 1.0 2012/08/22* @author dongliyang*/@SuppressWarnings("serial")public class SecurityCodeImageAction extends ActionSupport implements SessionAware{//Struts2中Map類型的sessionprivate Map<String, Object> session;//圖片流private ByteArrayInputStream imageStream;public ByteArrayInputStream getImageStream() {return imageStream;}public void setImageStream(ByteArrayInputStream imageStream) {this.imageStream = imageStream;}public String execute() throws Exception {//如果開啟Hard模式,可以不區(qū)分大小寫// String securityCode = SecurityCode.getSecurityCode(4,SecurityCodeLevel.Hard, false).toLowerCase();//獲取默認(rèn)難度和長(zhǎng)度的驗(yàn)證碼String securityCode = SecurityCode.getSecurityCode();imageStream = SecurityImage.getImageAsInputStream(securityCode);//放入session中session.put("SESSION_SECURITY_CODE", securityCode);return SUCCESS;}public void setSession(Map<String, Object> session) {this.session = session;}}第四步:配置Struts.xml <package name="Security" namespace="/Security" extends="struts2"><action name="SecurityCodeImageAction" class="com.dong.security.action.SecurityCodeImageAction"><result name="success" type="stream"><param name="contentType">image/jpeg</param><param name="inputName">imageStream</param><param name="bufferSize">2048</param></result></action></package>
第五步:前臺(tái)jsp和js <script type="text/javascript">function changeValidateCode(obj) {//獲取當(dāng)前的時(shí)間作為參數(shù),無具體意義 var timenow = new Date().getTime();//每次請(qǐng)求需要一個(gè)不同的參數(shù),否則可能會(huì)返回同樣的驗(yàn)證碼 //這和瀏覽器的緩存機(jī)制有關(guān)系,也可以把頁面設(shè)置為不緩存,這樣就不用這個(gè)參數(shù)了。 obj.src = "SecurityCodeImageAction?d=" + timenow;} </script>
<img src="Security/SecurityCodeImageAction" id="Verify" style="cursor:hand;" alt="看不清,換一張"/><input type="text" name="securityCode"/>
這就是驗(yàn)證碼生成的全過程,分享一下!
總結(jié)
以上是生活随笔為你收集整理的Struts2 验证码图片实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 后端开发应该掌握的 Redis 基础
- 下一篇: and or not 优先级_快速划分测