[理論知識]javascript
在java程序開發中,要顯示一張圖片,主要有兩種方式。第一種是基於現成圖片,這種方式比較常見也比較簡單。第二種是使用java中java.awt包和com.sun.image包中的繪圖技術,使用代碼繪製出一張圖片,這種技術通常適用於圖片並不是固定、重複使用率較低的場景,好比驗證碼、圖片加水印、生成縮略圖、繪製各類數據分析圖(柱狀圖、餅圖、線性圖等),這些圖片並非固定的,而是根據數據的改變而隨時變化的。java
[步驟解讀一]繪製驗證碼瀏覽器
本文中,小博老師就爲你們解析一下,如何使用java繪圖技術來製做驗證碼,因爲驗證碼的功能比較經常使用,代碼又比較繁瑣,所以小博老師先爲你們封裝一個Identifying類,之後要使用驗證碼就能夠直接調用它了,核心代碼以下:session
package com.bwf.framework.javaee.imageutils;dom
import java.awt.Color;jsp
import java.awt.Font;ide
import java.awt.Graphics2D;post
import java.awt.image.BufferedImage;this
import java.io.IOException;.net
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
* 驗證碼圖片生成Servlet類,直接調用該Servlet便可使用 取值的時候調用session.getAttribute("code")獲得生成的值
* @author 博爲峯-小博老師
* @time 2016-11-1 下午14:26:00
*/
public class Identifying extends HttpServlet {
public Identifying(HttpServletRequest request, HttpServletResponse response){
this.setRequest(request);
this.setResponse(response);
}
private static final long serialVersionUID = 1L; // 對象序列號
private int width = 120; // 畫布寬度(px)
private int height = 30; // 畫布高度(px)
private int lineNum = 150; // 干擾線數量
private int pointNum = 100; // 干擾點數量
private int wordNum = 4; // 驗證碼字符個數
private HttpServletRequest request; // 當前請求對象
private HttpServletResponse response; // 當前響應對象
private String sessionName = "code"; // 正確驗證碼存放在Session對象中的key名稱
/**
* 獲取範圍內的隨機顏色
* @param fc 顏色範圍的最大值(0~255)
* @param bc 顏色範圍的最小值(0~255)
* @return 隨機顏色值
*/
private Color getRandColor(int fc, int bc) {
Random random = new Random();
if (fc > 255)
fc = 255;
if (fc < 0)
fc = 0;
if (bc > 255)
bc = 255;
if (bc < 0)
bc = 0;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
/**
* 繪製驗證碼圖片
*/
public void create() throws IOException, ServletException {
// 設置輸出類型爲圖片
response.setContentType("image/jpeg");
// 獲取畫布寬度和高度
int width = this.width;
int height = this.height;
// 產生隨機數
Random r = new Random();
// 產生緩衝畫布
BufferedImage imgbuf = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 取得緩衝的繪製環境
Graphics2D g = imgbuf.createGraphics();
// 設置筆觸顏色 用來填充畫布的顏色
g.setColor(getRandColor(200, 250));
// 填充畫布
g.fillRect(0, 0, width, height);
// 設計筆觸顏色 用來繪製干擾線
g.setColor(getRandColor(160, 200));
// 隨機產生lineNum條幹擾線,使圖象中的認證碼不易被其它程序探測到
for (int i = 0; i < this.lineNum; i++) {
int x = r.nextInt(width); // 干擾線起始點x軸座標
int y = r.nextInt(height); // 干擾線起始點y軸座標
int xl = r.nextInt(12); // 干擾線結束點x軸座標
int yl = r.nextInt(12); // 干擾線結束點y軸座標
g.drawLine(x, y, x + xl, y + yl); // 繪製干擾線
}
// 設置筆觸顏色 用來繪製干擾點
g.setColor(getRandColor(120, 240));
// 隨機產生pointNum個干擾點,使圖像中的驗證碼不易被其餘分析程序探測到
for (int i = 0; i < this.pointNum; i++) {
int x = r.nextInt(width); // 設置干擾點中心點x軸座標
int y = r.nextInt(height); // 設置干擾點中心點y軸座標
g.drawOval(x, y, 0, 0); // 繪製干擾點,半徑0,起始角度0
}
// 設置文字樣式 用來繪製驗證碼字符
g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
// 準備一個ArrayList 用於存放驗證碼字符庫
ArrayList libs = new ArrayList();
// 準備一個char[] 列出驗證碼字符庫
char[] arr = new char[] { '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', '0', '1', '2', '3', '4', '5', '6','7', '8', '9' };
// 將char[]中的驗證碼字符 存放到 ArrayList中
for (int i = 0; i <= arr.length - 1; i++) {
libs.add(arr[i] + "");
}
// 隨機打亂順序
Collections.shuffle(libs);
// 定義字符串 用於拼接正確驗證碼
String scode = "";
// 循環出wordNum個驗證碼字符
for (int i = 0; i < this.wordNum; i++) {
// 從隨機驗證碼字符庫 抽取一個驗證碼字符
String rand = String.valueOf(libs.get(i));
// 拼接正確驗證碼
scode += rand;
// 設置筆觸顏色 用於繪製驗證碼字符
g.setColor(new Color(20 + r.nextInt(110), 20 + r.nextInt(110), 20 + r.nextInt(110)));
// 繪製驗證碼字符
g.drawString(rand, (this.width / this.wordNum / 2 + 12) * i + (this.width / this.wordNum / 2),this.height / 2 + 6);
}
// 將正確驗證碼存放到Session對象中
request.getSession().setAttribute(this.sessionName, scode);
// 獲得HTTP的流
ServletOutputStream out = response.getOutputStream();
// 產生JPEG的圖像加碼器
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
// 將圖像畫布內容轉碼
encoder.encode(imgbuf);
// 輸出圖像
out.flush();
}
……省略getter和setter……
}
而後咱們在一個Servlet,實例化Identifying對象,調用create()方法,便可顯示出一個驗證碼圖片,核心代碼以下:
@WebServlet("/BWFIdentifying")
public class BWFIdentifyingServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Identifying iden = new Identifying(request, response);
iden.create();
}
}
瀏覽器訪問效果以下:
[步驟解讀二]在登陸頁面中引入驗證碼
接下來咱們製做一個簡單的登陸頁面,引入驗證碼,咱們建立一個jsp,核心代碼以下:
<body>
<form action="BWFCheckLogin" method="post">
帳戶名稱:<input type="text" name="username"/><br/><br/>
帳戶密碼:<input type="password" name="password"/><br/><br/>
驗證 碼:<input type="text" name="iden" style="width:60px;"/>
<img src="BWFIdentifying" title="看不清?點擊換一張!" style="cursor:pointer;" id="iden" /><br/><br/>
<input type="submit" value="登 錄"/>
</form>
</body>
訪問jsp頁面效果以下:
爲了實現驗證碼圖片點擊後能夠自動更換一張驗證碼的效果,咱們在該jsp頁面中增長javascript,核心代碼以下:
<script>
window.onload=function(){
document.getElementById("iden").onclick=function(){
this.src="BWFIdentifying?a="+Math.random();
}
}
</script>
其中在URL中傳遞參數a,使用隨機數做爲值,是爲了讓該Servlet認爲每次都是新的請求。
這樣,咱們的驗證碼效果基本就作完了,當用戶點擊登陸按鈕,提交頁面後,咱們只須要獲取表單提交的用戶填寫的驗證碼,而後從Session對象(默認key爲「Code」)獲取正確的驗證碼,進行比對便可。
[步驟解讀三]Identifying類的經常使用方法
小博老師爲你們封裝的Identifying類,除了上述默認使用方式,還能夠按照本身的需求,設置經常使用參數,例如:
@WebServlet("/BWFIdentifying")
public class BWFIdentifyingServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Identifying iden = new Identifying(request, response);
iden.setWidth(300); // 設置驗證碼畫布寬度
iden.setHeight(50); // 設置驗證碼畫布高度
iden.setLineNum(30); // 設置干擾線數量
iden.setPointNum(50); // 設置干擾點屬相
iden.setWordNum(6); // 設置驗證碼字符數量
// 設置正確驗證碼存放Session對象的key名稱
iden.setSessionName("iden"); i
den.create();
}
}
訪問後效果: