生成验证码后台
@PostMapping("getImageCodes")public String getImageCodes(HttpServletRequest request){//1.獲取驗(yàn)證碼隨機(jī)字符String code = ImageCodeUtil.getSecurityCode();log.info("驗(yàn)證碼為:{}",code);//2.存儲(chǔ)驗(yàn)證碼隨機(jī)字符request.getServletContext().setAttribute("code",code);String imgBase64 = null;try {//3.生成驗(yàn)證碼圖片將驗(yàn)證碼圖片轉(zhuǎn)為Base64格式imgBase64 = ImageCodeUtil.careateImgBase64(code);} catch (IOException e) {e.printStackTrace();}return imgBase64;}
util工具包
import org.apache.commons.io.output.ByteArrayOutputStream;import org.springframework.util.Base64Utils;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.BufferedImage;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.Arrays;import java.util.Base64;import java.util.Random;import java.util.Base64;import java.util.Base64.Encoder;public class ImageCodeUtil {/*** 驗(yàn)證碼難度級(jí)別 Simple-數(shù)字 Medium-數(shù)字和小寫(xiě)字母 Hard-數(shù)字和大小寫(xiě)字母*/public enum SecurityCodeLevel {Simple, Medium, Hard};/*** 產(chǎn)生默認(rèn)驗(yàn)證碼,4位中等難度** @return*/public static String getSecurityCode() {return getSecurityCode(4, SecurityCodeLevel.Medium, false);}/*** 產(chǎn)生長(zhǎng)度和難度任意的驗(yàn)證碼** @param length* @param level* @param isCanRepeat* @return*/public static String getSecurityCode(int length, SecurityCodeLevel level, boolean isCanRepeat) {// 隨機(jī)抽取len個(gè)字符int len = length;// 字符集合(--除去易混淆的數(shù)字0,1,字母l,o,O)char[] codes = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', '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', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};// 根據(jù)不同難度截取字符串if (level == SecurityCodeLevel.Simple) {codes = Arrays.copyOfRange(codes, 0, 10);} else if (level == SecurityCodeLevel.Medium) {codes = Arrays.copyOfRange(codes, 0, 36);}// 字符集和長(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));}// 存放抽取出來(lái)的字符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è)置為code[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è)置為code[r]存放的數(shù)值result[i] = codes[r];// 必須確保不會(huì)再次抽取到那個(gè)字符,這里用數(shù)組中最后一個(gè)字符改寫(xiě)code[r],并將n-1codes[r] = codes[n - 1];n--;}}return String.valueOf(result);}/*** 生成驗(yàn)證碼圖片* @param securityCode* @return*/public static BufferedImage createImage(String securityCode){int codeLength = securityCode.length();//驗(yàn)證碼長(zhǎng)度int fontSize = 18;//字體大小int fontWidth = fontSize+1;//圖片寬高int width = codeLength*fontWidth+6;int height = fontSize*2+1;//圖片BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g = image.createGraphics();g.setColor(Color.WHITE);//設(shè)置背景色g.fillRect(0, 0, width, height);//填充背景g.setColor(Color.LIGHT_GRAY);//設(shè)置邊框顏色g.setFont(new Font("Arial", Font.BOLD, height-2));//邊框字體樣式g.drawRect(0, 0, width-1, height-1);//繪制邊框//繪制噪點(diǎn)Random rand = new Random();g.setColor(Color.LIGHT_GRAY);for (int i = 0; i < codeLength*6; i++) {int x = rand.nextInt(width);int y = rand.nextInt(height);g.drawRect(x, y, 1, 1);//繪制1*1大小的矩形}//繪制驗(yàn)證碼int codeY = height-10;g.setColor(new Color(19,148,246));//Georgia 是個(gè)字體,如果想用中文要指定中文字體;eg:"宋體";//g.setFont(new Font("Georgia", Font.BOLD, fontSize));g.setFont(new Font("宋體", Font.BOLD, fontSize));for(int i=0;i<codeLength;i++){double deg=new Random().nextDouble()*20;g.rotate(Math.toRadians(deg), i*16+13,codeY-7.5);g.drawString(String.valueOf(securityCode.charAt(i)), i*16+5, codeY);g.rotate(Math.toRadians(-deg), i*16+13,codeY-7.5);}g.dispose();//關(guān)閉資源return image;}/*** 創(chuàng)建驗(yàn)證碼圖片轉(zhuǎn)為Base64* @param code 驗(yàn)證碼隨機(jī)字符* */public static String careateImgBase64(String code) throws IOException {//生成圖片BufferedImage image = createImage(code);//創(chuàng)建io流ByteArrayOutputStream baos = new ByteArrayOutputStream();//寫(xiě)入流中ImageIO.write(image, "png", baos);//轉(zhuǎn)換成字節(jié)byte[] bytes = baos.toByteArray();//獲取編碼對(duì)象Encoder encoder = Base64.getEncoder();//獲取base64編碼字符串String png_base64 = encoder.encodeToString(bytes);//刪除 \r\npng_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//ImageIO.write(bufferedImage, "png", new File("D:/qrcode1.png"));//System.out.println("值為:"+"data:image/png;base64,"+png_base64);//返回字符串String pngBase64="data:image/png;base64," + png_base64;return pngBase64;}//測(cè)試public static void main(String[] args) throws IOException{//獲得隨機(jī)字符String securityCode = getSecurityCode();//打印隨機(jī)字符System.out.println("===="+securityCode);//生成圖片BufferedImage image = createImage(securityCode);//將生成的驗(yàn)證碼圖片以png(1.png)的格式輸出到D盤(pán) "D:\\1.png" == "D:/1.png"ImageIO.write(image, "png", new FileOutputStream(new File("D:\\5.png")));/*//生成圖片BufferedImage image = createImage(securityCode);//創(chuàng)建io流ByteArrayOutputStream baos = new ByteArrayOutputStream();//寫(xiě)入流中ImageIO.write(image, "png", baos);//轉(zhuǎn)換成字節(jié)byte[] bytes = baos.toByteArray();//獲取編碼對(duì)象Encoder encoder = Base64.getEncoder();//獲取base64編碼字符串String png_base64 = encoder.encodeToString(bytes);//刪除 \r\npng_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//ImageIO.write(bufferedImage, "png", new File("D:/qrcode1.png"));//System.out.println("值為:"+"data:image/png;base64,"+png_base64);//返回字符串String pngBase64="data:image/png;base64," + png_base64;System.out.println(pngBase64);*/}}總結(jié)
- 上一篇: ElementUI+VUE 日期控件禁用
- 下一篇: Ajax技术简单入门