生成驗證碼的幾種方式
阿新 • • 發佈:2018-12-13
生成驗證碼的幾種方式
1,在jsp頁面中直接生成驗證碼
image.jsp原始碼:
//image.jsp <%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" pageEncoding="GBK"%> <%!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); }%> <% //設定頁面不快取 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); // 在記憶體中建立圖象 // 通過這裡可以修改圖片大小 int width = 85, height = 23; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 獲取圖形上下文 // g相當於筆 Graphics g = image.getGraphics();//生成隨機類 Random random = new Random(); // 設定背景色 g.setColor(getRandColor(200, 250)); // 畫一個實心的長方,作為北京 g.fillRect(0, 0, width, height); //設定字型 g.setFont(new Font("黑體", Font.PLAIN, 18)); //畫邊框 g.setColor(Color.BLUE); g.drawRect(0,0,width-1,height-1); // 隨機產生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); } // 取隨機產生的認證碼(4位數字) //String rand = request.getParameter("rand"); //rand = rand.substring(0,rand.indexOf(".")); String sRand = ""; // 如果要使用中文,必須定義字型檔,可以使用陣列進行定義 // 這裡直接寫中文會出亂碼,必須將中文轉換為unicode編碼 String[] str = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "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", "s", "t", "u", "v", "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; for (int i = 0; i < 5; i++) { String rand = str[random.nextInt(str.length)]; sRand += rand; // 將認證碼顯示到圖象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random .nextInt(110), 20 + random.nextInt(110)));//呼叫函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成 g.drawString(rand, 16 * i + 6, 19); } // 將認證碼存入SESSION session.setAttribute("rand", sRand); // 圖象生效 g.dispose(); // 輸出圖象到頁面 ImageIO.write(image, "JPEG", response.getOutputStream()); out.clear(); out = pageContext.pushBody(); %>
login.jsp原始碼(使用驗證碼的頁面):
//使用驗證碼的頁面login.jsp <%@ page contentType="text/html" pageEncoding="GBK"%> <html> <head> <title>登陸頁面</title> <script> function reloadImage() { document.getElementById('identity').src = 'image.jsp?ts=' + new Date() .getTime(); } </script> </head> <body> <center> <% // 亂碼解決 request.setCharacterEncoding("GBK"); %> <h1> 登陸程式 </h1> <hr> <%=request.getAttribute("info") != null ? request .getAttribute("info") : ""%> <form action="check.jsp" method="post"> 使用者ID: <input type="text" name="mid"> <br> 密 碼: <input type="password" name="password"> <br> 驗證碼: <input type="text" name="code" maxlength="5" size="5"> <img src="image.jsp" id="identity" onclick="reloadImage()" title="看不清,點選換一張"> <br> <input type="submit" value="登陸"> <input type="reset" value="重置"> </form> </center> </body> </html>
效果如下:
2,使用Servlet生成驗證碼
IdentityServlet.java原始碼:
//IdentityServlet.java程式碼如下: package com.helloweenvsfei.servlet; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class IdentityServlet extends HttpServlet { /** * */ private static final long serialVersionUID = -479885884254942306L; public static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; public static Random random = new Random(); public static String getRandomString() { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < 6; i++) { buffer.append(CHARS[random.nextInt(CHARS.length)]); } return buffer.toString(); } public static Color getRandomColor() { return new Color(random.nextInt(255), random.nextInt(255), random .nextInt(255)); } public static Color getReverseColor(Color c) { return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c .getBlue()); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("image/jpeg"); String randomString = getRandomString(); request.getSession(true).setAttribute("randomString", randomString); int width = 100; int height = 30; Color color = getRandomColor(); Color reverse = getReverseColor(color); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bi.createGraphics(); g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16)); g.setColor(color); g.fillRect(0, 0, width, height); g.setColor(reverse); g.drawString(randomString, 18, 20); for (int i = 0, n = random.nextInt(100); i < n; i++) { g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1); } // 轉成JPEG格式 ServletOutputStream out = response.getOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(bi); out.flush(); } public static void main(String[] args) { System.out.println(getRandomString()); } }
Web..xml原始碼:
//Web.xml的配置為: <servlet> <servlet-name>IdentityServlet</servlet-name> <servlet-class>com.helloweenvsfei.servlet.IdentityServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>IdentityServlet</servlet-name> <url-pattern>/servlet/IdentityServlet</url-pattern> </servlet-mapping>
identity.html原始碼:
//測試頁面identity.html為: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>identity.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=GB18030"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body> <script> function reloadImage() { document.getElementById('btn').disabled = true; document.getElementById('identity').src='servlet/IdentityServlet?ts=' + new Date().getTime(); } </script> <img src="servlet/IdentityServlet" id="identity" onload="btn.disabled = false; " /> <input type=button value=" 換個圖片 " onclick="reloadImage()" id="btn"> </body> </html>
3,在Struts2應用中生成驗證碼
RandomNumUtil.java原始碼:
//RandomNumUtil.java package org.ml.util; 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.util.Random; import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; public class RandomNumUtil { public static final char[] CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; private ByteArrayInputStream image;// 影象 private String str;// 驗證碼 /** * 構造方法呼叫初始化屬性方法 */ private RandomNumUtil() { init(); } /** * 取得RandomNumUtil例項 */ public static RandomNumUtil Instance() { return new RandomNumUtil(); } /** * 取得驗證碼圖片 */ public ByteArrayInputStream getImage() { return this.image; } /** * 取得圖片的驗證碼 */ public String getString() { return this.str; } /** * 初始化屬性否具體方法 */ private void init() { // 在記憶體中建立圖象 int width = 85, height = 18; //設定圖形的高度和寬度,以及RGB型別 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 獲取圖形上下文 Graphics g = image.getGraphics(); // 生成隨機類 Random random = new Random(); // 設定背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width, height); // 設定字型 g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 隨機產生255條幹擾線,使圖象中的認證碼不易被其它程式探測到 g.setColor(getRandColor(160, 200)); for (int i = 0; i < 255; 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位數字) StringBuffer sRand = new StringBuffer(); for (int i = 0; i < 6; i++) { String rand = String.valueOf(CHARS[random.nextInt(CHARS.length-1)]);//從字元陣列中隨機產生一個字元 sRand.append(rand); // 將認證碼顯示到圖象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); // 呼叫函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成 g.drawString(rand, 13 * i + 6, 17); } // 賦值驗證碼 this.str = sRand.toString(); // 圖象生效 g.dispose(); //下面將生成的圖形轉變為圖片 ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayInputStream input = null; try { ImageOutputStream imageOut = ImageIO.createImageOutputStream(output); ImageIO.write(image, "JPEG", imageOut);//將影象按JPEG格式寫入到imageOut中,即存入到output的位元組流中 imageOut.close();//關閉寫入流 input = new ByteArrayInputStream(output.toByteArray());//input讀取output中的影象資訊 } catch (Exception e) { System.out.println("驗證碼圖片產生出現錯誤:" + e.toString()); } this.image = 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); } }
RandomAction.java原始碼:
//RandomAction.java的程式碼: package org.ml.action; import java.io.ByteArrayInputStream; import org.ml.util.RandomNumUtil; import com.opensymphony.xwork2.ActionContext; 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());// 取得帶有隨機字串的圖片 ActionContext.getContext().getSession().put("random", rdnu.getString());// 取得隨機字串放入HttpSession return SUCCESS; } public void setInputStream(ByteArrayInputStream inputStream) { this.inputStream = inputStream; } public ByteArrayInputStream getInputStream() { return inputStream; } }
struts.xml配置:
//struts.xml配置為: <!-- Random驗證碼 --> <action name="rand" class="org.ml.action.RandomAction"> <result type="stream" name="success"> <param name="contentType">image/JPEG</param> <param name="inputName">inputStream</param> </result> </action>
HTML中的表單原始碼:
//HTML中的表單程式碼為: <tr height="35" > <td width="14%" class="top_hui_text"> <span class="login_txt"> 驗證碼: </span> </td> <td colspan="2" class="top_hui_text"> <input type="text" name="rand" id="rand" size="6" maxlength="6"> <script type="text/javascript"> function changeValidateCode(obj) { //獲取當前的時間作為引數,無具體意義 var timenow = new Date().getTime(); //每次請求需要一個不同的引數,否則可能會返回同樣的驗證碼 //這和瀏覽器的快取機制有關係,也可以把頁面設定為不快取,這樣就不用這個引數了。 obj.src="rand.action?d="+timenow; } </script> <img src="rand.action" title="點選圖片重新整理驗證碼" onclick="changeValidateCode(this)" height="22" width="80" /> </td> </tr>