java生成圖片驗證碼返回base64圖片信息方式
java生成圖片驗證碼返回base64圖片
一般在生成驗證碼,有兩種形式:
- 前端js生成,并在前端驗證通過,提交表單到后臺。安全性較低,很容易被識別
- 后端生成返回給前端展示,提交用戶驗證碼到后臺驗證通過。安全性較前端方式高,因為整個驗證過程在后臺。
其實驗證碼也沒有絕對的安全,只能說后端的處理方式比前端好一些而已,所以這個示例是利用java后臺生成二維碼圖片,并返回給前端base64格式,展示給用戶,后臺將二維碼真值保存在session,用戶提交輸入的驗證碼和保存的真值做比較,然后返回前臺是否驗證成功。
1.創(chuàng)建一個驗證碼生成工具類
此類為靜態(tài)類
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.Serializable; import java.util.Random; import javax.imageio.ImageIO; import org.apache.commons.lang3.RandomUtils; import com.alibaba.druid.util.Base64; /** * * @ClassName: ValidateCodeUtil * @Description: 驗證碼生成工具類 * @author chenhx * @date 2017年11月14日 上午11:00:07 */ public class ValidateCodeUtil { private static Validate validate = null; //驗證碼類,用于最后返回此對象,包含驗證碼圖片base64和真值 private static Random random = new Random(); //隨機類,用于生成隨機參數(shù) private static String randString = "0123456789abcdefghijkmnpqrtyABCDEFGHIJLMNQRTY";//隨機生成字符串的取值范圍 private static int width = 80; //圖片寬度 private static int height = 34; //圖片高度 private static int StringNum = 4; //字符的數(shù)量 private static int lineSize = 40; //干擾線數(shù)量 //將構造函數(shù)私有化 禁止new創(chuàng)建 private ValidateCodeUtil() { super(); } /** * 獲取隨機字符,并返回字符的String格式 * @param index (指定位置) * @return */ private static String getRandomChar(int index) { //獲取指定位置index的字符,并轉換成字符串表示形式 return String.valueOf(randString.charAt(index)); } /** * 獲取隨機指定區(qū)間的隨機數(shù) * @param min (指定最小數(shù)) * @param max (指定最大數(shù)) * @return */ private static int getRandomNum(int min,int max) { return RandomUtils.nextInt(min, max); } /** * 獲得字體 * @return */ private static Font getFont() { return new Font("Fixedsys", Font.CENTER_BASELINE, 25); //名稱、樣式、磅值 } /** * 獲得顏色 * @param fc * @param bc * @return */ private static Color getRandColor(int frontColor, int backColor) { if(frontColor > 255) frontColor = 255; if(backColor > 255) backColor = 255; int red = frontColor + random.nextInt(backColor - frontColor - 16); int green = frontColor + random.nextInt(backColor - frontColor -14); int blue = frontColor + random.nextInt(backColor - frontColor -18); return new Color(red, green, blue); } /** * 繪制字符串,返回繪制的字符串 * @param g * @param randomString * @param i * @return */ private static String drawString(Graphics g, String randomString, int i) { Graphics2D g2d = (Graphics2D) g; g2d.setFont(getFont()); //設置字體 g2d.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat()));//設置顏色 String randChar = String.valueOf(getRandomChar(random.nextInt(randString.length()))); randomString += randChar; //組裝 int rot = getRandomNum(5,10); g2d.translate(random.nextInt(3), random.nextInt(3)); g2d.rotate(rot * Math.PI / 180); g2d.drawString(randChar, 13*i, 20); g2d.rotate(-rot * Math.PI / 180); return randomString; } /** * 繪制干擾線 * @param g */ private static void drawLine(Graphics g) { //起點(x,y) 偏移量x1、y1 int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(13); int yl = random.nextInt(15); g.setColor(new Color(random.nextFloat(), random.nextFloat(), random.nextFloat())); g.drawLine(x, y, x + xl, y + yl); } /** * * @MethodName: getRandomCode * @Description: 生成Base64圖片驗證碼 * @param key * @return String 返回base64 */ public static Validate getRandomCode() { validate = validate==null?new Validate():validate; // BufferedImage類是具有緩沖區(qū)的Image類,Image類是用于描述圖像信息的類 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); Graphics g = image.getGraphics();// 獲得BufferedImage對象的Graphics對象 g.fillRect(0, 0, width, height);//填充矩形 g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//設置字體 g.setColor(getRandColor(110, 133));//設置顏色 //繪制干擾線 for(int i = 0; i <= lineSize; i++) { drawLine(g); } //繪制字符 String randomString = ""; for(int i = 1; i <= StringNum; i++) { randomString = drawString(g, randomString, i); validate.setValue(randomString); } g.dispose();//釋放繪圖資源 ByteArrayOutputStream bs = null; try { bs = new ByteArrayOutputStream(); ImageIO.write(image, "png", bs);//將繪制得圖片輸出到流 String imgsrc = Base64.byteArrayToBase64(bs.toByteArray()); validate.setBase64Str(imgsrc); } catch (Exception e) { e.printStackTrace(); } finally { try { bs.close(); } catch (IOException e) { e.printStackTrace(); }finally{ bs = null; } } return validate; } /** * * @ClassName: Validate * @Description: 驗證碼類 * @author chenhx * @date 2017年11月14日 上午11:35:34 */ public static class Validate implements Serializable{ private static final long serialVersionUID = 1L; private String Base64Str; //Base64 值 private String value; //驗證碼值 public String getBase64Str() { return Base64Str; } public void setBase64Str(String base64Str) { Base64Str = base64Str; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } }
2.在java接口中使用
Validate v = ValidateCodeUtil.getRandomCode(); //直接調用靜態(tài)方法,返回驗證碼對象 if(v!=null){ session.setAttribute("validate", MD5Util.md5(v.getValue().toLowerCase())); //將驗證碼值保存session result.setResult(v.getBase64Str()); result.setResultCode(0); result.setMsg("刷新驗證碼成功"); }
3.前端接收返回的base64
然后展示在頁面上
<img id="validateImg" src="data:image/png;base64,${validate }" alt="點擊刷新" />
具體的ajax請求什么的,我就不詳細寫了,反正關鍵信息就是這些。
最后效果是這樣:
ValidateCodeUtil類中使用了其他的jar包,org.apache.commons.lang3.RandomUtils和com.alibaba.druid.util.Base64。
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringMVC + jquery.uploadify實現(xiàn)上傳文件功能
文件上傳是很多項目都會使用到的功能,SpringMVC當然也提供了這個功能。不過小編不建議在項目中通過form表單來提交文件上傳,這樣做的局限性很大。下面這篇文章主要介紹了利用SpringMVC + jquery.uploadify實現(xiàn)上傳文件功能的相關資料,需要的朋友可以參考下。2017-06-06SpringBoot2整合Redis多數(shù)據(jù)源步驟詳解
這篇文章主要介紹了SpringBoot2整合Redis多數(shù)據(jù)源步驟詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03Java集合Map的clear與new Map區(qū)別詳解
這篇文章主要介紹了Java集合Map的clear與new Map區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04