一、先寫一個驗證碼工具類別
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實作登入驗證碼(程式碼全)的詳細內容。更多資訊請關注PHP中文網其他相關文章!