一、先寫一個驗證碼工具類
package com.yx.cus.util;import java.awt.BasicStroke;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 java.util.Random;import javax.imageio.ImageIO;public class VerifyCode { private int w = 70; private int h = 35; private Random r = new Random(); // {"宋體", "華文楷體", "黑體", "華文新魏", "華文隸書", "微軟雅黑", "楷體_GB2312"} private String[] fontNames = {"宋體", "華文楷體", "黑體", "微軟雅黑", "楷體_GB2312"}; private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; private Color bgColor = new Color(255, 255, 255); public static String text ; private Color randomColor () { int red = r.nextInt(150); int green = r.nextInt(150); int blue = r.nextInt(150); return new Color(red, green, blue); } private Font randomFont () { int index = r.nextInt(fontNames.length); String fontName = fontNames[index]; int style = r.nextInt(4); int size = r.nextInt(5) + 24; return new Font(fontName, style, size);//指定字型名稱、樣式和點大小,建立一個新 Font。 } //畫幹擾的線條 private void drawLine (BufferedImage image) { int num = 3;//畫三條 Graphics2D g2 = (Graphics2D)image.getGraphics(); for(int i = 0; i < num; i++) { int x1 = r.nextInt(w); int y1 = r.nextInt(h); int x2 = r.nextInt(w); int y2 = r.nextInt(h); g2.setStroke(new BasicStroke(1.5F)); g2.setColor(Color.BLUE); g2.drawLine(x1, y1, x2, y2); } } private char randomChar () { int index = r.nextInt(codes.length()); return codes.charAt(index); } private BufferedImage createImage () { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D)image.getGraphics(); g2.setColor(this.bgColor); g2.fillRect(0, 0, w, h); return image; } public BufferedImage getImage () { BufferedImage image = createImage(); Graphics2D g2 = (Graphics2D)image.getGraphics(); StringBuilder sb = new StringBuilder(); // 向圖片中畫4個字元 for(int i = 0; i < 4; i++) { String s = randomChar() + ""; sb.append(s); float x = i * 1.0F * w / 4; g2.setFont(randomFont()); g2.setColor(randomColor()); /** * 首字元的基準位於使用者空間的 (x, h-5) 位置處 * 原點在左上方,X軸遞增的方向是從左向右;Y軸是從上到下 * 在提供的座標位於基準上最左邊字元的情況下,可以從右至左呈現字形 * h-5表示y軸方向,向上位移了5 */ g2.drawString(s, x, h-5); } this.text = sb.toString(); drawLine(image); return image; } public String getText () { return text; } public static void output (BufferedImage image, OutputStream out) throws IOException { ImageIO.write(image, "JPEG", out); }}
這個工具類我們主要使用兩個方法:
1.通過getImage()方法來製作驗證碼,返回BufferedImage 類型的驗證碼
2.通過getText()方法擷取驗證碼的文本,返回String類型
二。驗證碼的介面(controller)
/** * 驗證碼 * @param request * @return * @throws Exception */@RequestMapping(value = "/VC", method = RequestMethod.POST)@ResponseBodypublic void VC(HttpServletRequest request, HttpServletResponse response ) throws Exception{ VerifyCode code=new VerifyCode(); BufferedImage image = code.getImage(); //將驗證碼文本存到Redis vckey=IDUtil.nextId(); JedisClient.set(vckey, code.getText(),60); ImageIO.write(image,"jpg",response.getOutputStream()); }
該介面會返回前端一個驗證碼,是以流的形式返回的,在返回之前會產生一個唯一的標識賦給一個全域變數,用來在redis裡存入該驗證碼的文本,以作後用,存入的文本有時間限制
三、擷取驗證碼文本標識的介面(就是存入驗證碼文本的值)
/** * 驗證碼文本的標識 * @param request * @return * @throws Exception */ @RequestMapping(value = "/VCkey", method = RequestMethod.POST)@ResponseBodypublic String VCkey(HttpServletRequest request, HttpServletResponse response ) throws Exception{ System.out.println(vckey); return vckey;}
該介面主要就是把在redis裡存驗證碼文本的鍵返回給前端,然後在登入的時候一起傳回登入的介面
四、登入介面(試例)
String user_phone = reqstr.get("user_phone");//帳號String user_pwd = reqstr.get("user_pwd");//密碼String vc = reqstr.get("vc").toLowerCase();//使用者輸入的驗證碼String vckey = reqstr.get("vckey");//前端擷取的驗證碼文本的鍵(標識)String vcode= (String)JedisClient.get(vckey);//通過標識從redis裡擷取驗證碼文本if(vc.equals(vcode.toLowerCase())) {//使用者輸入的驗證碼與redsi存的作比較 “驗證碼成功”}else if(vcode==null){ “驗證碼以到期”}else{ “驗證碼錯誤”}
補充:驗證碼的鍵(標識)也可以在前端產生,比如產生一個時間戳記,在請求驗證碼的介面時作為參數傳入,這樣後台就可以少寫一個介面和全域變數
相關文章:
java登入驗證碼實現代碼
JavaScript登入驗證碼的實現