Java中使用圖片驗證碼
一、第一種方式
- 工具類
@WebServlet("/BufferImage")
public class BufferImage extends HttpServlet {
public static final int WIDTH = 120;//生成圖片的寬度
public static final int HEIGHT = 30;//生成圖片的高度
public static final int WORDS_NUMBER = 4;//驗證碼中字符的個數
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// TODO Auto-generated method stub
String createTypeFlag = req.getParameter("createTypeFlag");//接收客戶端傳遞的createTypeFlag標識
//在內存中創建一張圖片
BufferedImage bi = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_3BYTE_BGR);
//得到圖片
Graphics g = bi.getGraphics();
//設置圖片的背景色
setBackGround(g);
//設置圖片的邊框
setBorder(g);
//在圖片上畫干擾線
drawRandomLine(g);
//在圖片上放上隨機字符
String randomString = this.drawRandomNum((Graphics2D)g, createTypeFlag);
System.out.println(randomString);
//將隨機數存在session中
req.getSession().setAttribute("checkcode", randomString);
//設置響應頭通知瀏覽器以圖片的形式打開
resp.setContentType("image/jpeg");
//設置響應頭控制瀏覽器不要緩存
resp.setDateHeader("expries", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
//將圖片傳給瀏覽器
ImageIO.write(bi, "jpg", resp.getOutputStream());
}
//設置圖片背景色
//@param g
private void setBackGround(Graphics g) {
//設置顏色
g.setColor(Color.WHITE);
//填充區域
g.fillRect(0, 0, WIDTH, HEIGHT);
}
/*
* 設置圖片的邊框
* @param g
* */
private void setBorder(Graphics g) {
//設置邊框顏色
g.setColor(Color.BLUE);
//邊框區域
g.drawRect(1, 1, WIDTH - 2, HEIGHT -2);
}
/*
* 在圖片上畫隨機線條
* @param g
* */
private void drawRandomLine(Graphics g) {
//設置顏色
g.setColor(Color.GREEN);
//設置線條個數並畫線
for ( int i = 0 ; i < 7 ; i++ ) {
int x1 = new Random().nextInt(WIDTH);
int y1 = new Random().nextInt(HEIGHT);
int x2 = new Random().nextInt(WIDTH);
int y2 = new Random().nextInt(HEIGHT);
g.drawLine(x1, y1, x2, y2);
}
}
/*
* 在圖片上畫隨機字符
* @param g
* @param createTypeFlag
* @return String
* */
private String drawRandomNum(Graphics g,String createTypeFlag) {
//設置顏色
g.setColor(Color.BLUE);
g.setFont(new Font("宋體",Font.BOLD,20));
//數字字母的組合
String baseNumLetter = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ";
String baseNum = "0123456789";
String baseLetter = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
if ( createTypeFlag != null && createTypeFlag.length() > 0 ) {
if( createTypeFlag.equals("nl") ) {
//截取數字和字母的組合
return createRandomChar((Graphics2D) g,baseNumLetter);
} else if ( createTypeFlag.equals("n") ) {
//截取數字的組合
return createRandomChar((Graphics2D) g,baseNum);
} else if ( createTypeFlag.equals("l") ) {
//截取字母的組合
return createRandomChar((Graphics2D) g,baseLetter);
}
} else {
//截取數字和字母的組合
return createRandomChar((Graphics2D) g,baseNumLetter);
}
return "";
}
/*
* 創建隨機字符
* @param g
* @param baseChar
* @return String
* */
private String createRandomChar(Graphics2D g , String baseChar) {
StringBuffer b = new StringBuffer();
int x = 5;
String ch = "";
for ( int i = 0 ; i < WORDS_NUMBER ; i++ ) {
//設置字體的旋轉角度
int degree = new Random().nextInt() % 30;
ch = baseChar.charAt(new Random().nextInt(baseChar.length())) + "";
b.append(ch);
//正向角度
g.rotate(degree * Math.PI / 180 , x,20);
g.drawString(ch, x, 20);
//反向角度
g.rotate(-degree * Math.PI / 180 , x,20);
x+=30;
}
return b.toString();
}
}
- 後端
@RequestMapping(value="/userLogin.do")
public void userLogin(String code,HttpSession session){
String cht=(String)session.getAttribute("checkcode");
if(code.equalsIgnoreCase(cht)){
System.out.println("驗證碼正確");
}
}
- 前端
<form>
<img src="BufferImage" οnclick="this.src='BufferImage?'+new Date().getTime()">看不清換一張<br><br>
驗證碼: <input type="text" id="verify" class="input-medium" placeholder="驗證碼">
<input type="submit" value="提交">
</form>
二、第二種方式(Spring Boot框架使用)
- 工具類
package com.zhiyou.util;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
public final class BufferImage {
// 驗證碼字符集
private static final char[] chars = {
'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'};
// 字符數量
private static final int SIZE = 4;
// 干擾線數量
private static final int LINES = 8;
// 寬度
private static final int WIDTH = 100;
// 高度
private static final int HEIGHT = 32;
// 字體大小
private static final int FONT_SIZE = 25;
/**
* 生成隨機驗證碼及圖片
* 數組中[驗證碼,圖片]
*/
public static Object[] createImage() {
StringBuffer sb = new StringBuffer();
// 1.創建空白圖片
BufferedImage image = new BufferedImage(
WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// 2.獲取圖片畫筆
Graphics graphic = image.getGraphics();
// 3.設置畫筆顏色
graphic.setColor(new Color(216, 172, 203, 241));
// 4.繪製矩形背景
graphic.fillRect(0, 0, WIDTH, HEIGHT);
// 5.畫隨機字符
Random ran = new Random();
for (int i = 0; i <SIZE; i++) {
// 取隨機字符索引
int n = ran.nextInt(chars.length);
// 設置隨機顏色
graphic.setColor(getRandomColor());
// 設置字體大小
graphic.setFont(new Font(
null, Font.BOLD + Font.ITALIC, FONT_SIZE));
// 畫字符
graphic.drawString(
chars[n] + "", i * WIDTH / SIZE, HEIGHT/2+HEIGHT/8);
// 記錄字符
sb.append(chars[n]);
}
// 6.畫干擾線
for (int i = 0; i < LINES; i++) {
graphic.setColor(getRandomColor());
// 隨機畫線
graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
ran.nextInt(WIDTH), ran.nextInt(HEIGHT));
}
// 7.返回驗證碼和圖片
return new Object[]{sb.toString(), image};
}
/**
* 隨機取色
*/
public static Color getRandomColor() {
Random ran = new Random();
Color color = new Color(ran.nextInt(256),
ran.nextInt(256), ran.nextInt(256));
return color;
}
public static void main(String[] args) throws IOException {
Object[] objs = createImage();
BufferedImage image = (BufferedImage) objs[1];
OutputStream os = new FileOutputStream("src/main/resources/static/picture/eb1ccd3d99794795bc99553b0b762e73.gif");
ImageIO.write(image, "png", os);
os.close();
}
}
- 後臺controller
/* **********************************圖片驗證碼************************************* */
@RequestMapping(value = "/BufferImage")
protected void createImg(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//1.生成隨機的驗證碼及圖片
Object[] objs = BufferImage.createImage();
//2.將驗證碼存入session
String imgcode = (String) objs[0];
HttpSession session = req.getSession();
session.setAttribute("checkcode", imgcode);
//3.將圖片輸出給瀏覽器
BufferedImage img = (BufferedImage) objs[1];
res.setContentType("image/png");
//服務器自動創建輸出流,目標指向瀏覽器
OutputStream os = res.getOutputStream();
ImageIO.write(img, "png", os);
os.close();
}
- 驗證和前臺方式不變