package com.xia;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
* @(#)VerifyCodeServlet.java Dec 9, 2007 8:14:14 PM
*
* @author Yuan
* 驗證碼生成器,使用此類需要將表單里的驗證碼輸入框的name屬性設為"verifycode"
*/
public class VerifyCodeGenerator {
public static final VerifyCodeGenerator generator = new VerifyCodeGenerator();
private final String ATTRIBUTE_NAME = "verifycode";
//圖片的寬度
private final int WIDTH = 15;
//圖片的高度
private final int HEIGHT = 22;
//字符串長度
private final int CODE_LENGTH = 4;
//隨機字符串范圍
private final String RAND_RANGE = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "1234567890" ;
private final char[] CHARS = RAND_RANGE.toCharArray();
private Random random = new Random();
public VerifyCodeGenerator(){
//
}
public static VerifyCodeGenerator getInstance(){
return generator;
}
/**
* 生成隨機字符串
* @return 隨機字符串
*/
private String getRandString(){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < CODE_LENGTH; i++)
sb.append(CHARS[random.nextInt(CHARS.length)]);
return sb.toString();
}
/**
* 生成隨機顏色
* @param ll 產生顏色值下限(lower limit)
* @param ul 產生顏色值上限(upper limit)
* @return 生成的隨機顏色對象
*/
private Color getRandColor(int ll, int ul){
if (ll > 255) ll = 255;
if (ll < 1) ll = 1;
if (ul > 255) ul = 255;
if (ul < 1) ul = 1;
if (ul == ll) ul = ll + 1;
int r = random.nextInt(ul - ll) + ll;
int g = random.nextInt(ul - ll) + ll;
int b = random.nextInt(ul - ll) + ll;
Color color = new Color(r,g,b);
return color;
}
/**
* 生成指定字符串的圖像數據
* @param verifyCode 即將被打印的隨機字符串
* @return 生成的圖像數據
* */
private BufferedImage getImage(String verifyCode){
BufferedImage image = new BufferedImage(WIDTH * CODE_LENGTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
//獲取圖形上下文
Graphics graphics = image.getGraphics();
//設置背景色
graphics.setColor(getRandColor(1,50));
//填充背景色
graphics.fillRect(0, 0, WIDTH * 4, HEIGHT);
//設置邊框顏色
graphics.setColor(new Color(0,255,0));
//畫邊框
/* for (int i=0; i<2; i++)
graphics.drawRect(i, i, WIDTH * CODE_LENGTH - i * 2 - 1, HEIGHT - i * 2 - 1); */
//設置隨機干擾線條顏色
graphics.setColor(getRandColor(50,100));
//產生50條干擾線條
for (int i=0; i<50; i++){
int x1 = random.nextInt(WIDTH * CODE_LENGTH - 4) + 2;
int y1 = random.nextInt(HEIGHT - 4) + 2;
int x2 = random.nextInt(WIDTH * CODE_LENGTH - 2 - x1) + x1;
int y2 = y1;
graphics.drawLine(x1, y1, x2, y2);
}
//設置字體
graphics.setFont(new Font("Times New Roman", Font.PLAIN, 18));
//畫字符串
for (int i=0; i<this.CODE_LENGTH; i++){
String temp = verifyCode.substring(i, i+1);
graphics.setColor(getRandColor(100,255));
graphics.drawString(temp, 13 * i + 6, 16);
}
//圖像生效
graphics.dispose();
return image;
}
/**
* 將驗證碼的圖像輸出
* @param request 用戶的請求對象
* @param response 用戶的響應對象
* */
public void printImage(HttpServletRequest request,
HttpServletResponse response){
//將ContentType設為"image/jpeg",讓瀏覽器識別圖像格式。
response.setContentType("image/jpeg");
//設置頁面不緩存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 2000);
//獲得隨機驗證碼
String verifyCode = this.getRandString();
String str = "ssss";
for(int i=0; i<10; i++)
str = str + str;
//獲得驗證碼的圖像數據
BufferedImage bi = this.getImage(verifyCode);
//把驗證碼存入session
request.getSession().setAttribute(ATTRIBUTE_NAME, verifyCode);
try{
//獲得Servlet輸出流
ServletOutputStream outStream = response.getOutputStream();
//創建可用來將圖像數據編碼為JPEG數據流的編碼器
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream);
//將圖像數據進行編碼
encoder.encode(bi);
//強行將緩沖區的內容輸入到頁面
outStream.flush();
//關閉輸出流
outStream.close();
}catch(IOException ex){
ex.printStackTrace();
}
}
/**
* 檢查輸入的驗證碼是否正確,若用戶輸入的驗證碼與生成的驗證碼相符則返回true,否則返回false。
* @param request 用戶的請求對象
* @return 驗證結果
* */
public boolean check(HttpServletRequest request){
if (((String)request.getParameter(ATTRIBUTE_NAME))
.equalsIgnoreCase((String)request.getSession().getAttribute(ATTRIBUTE_NAME))){
request.getSession().removeAttribute(ATTRIBUTE_NAME);
return true;
}
return false;
}
}
2. 編寫servlet顯示圖片信息
package com.xia;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CreateCode extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
VerifyCodeGenerator ver=new VerifyCodeGenerator();
ver.printImage(request, response);
}
}
3. 編寫HTML頁面:
<%@ page language="java" pageEncoding="utf-8"%>
<%String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<script type="text/javascript">
function show()
{
var o=document.getElementById("random");
var timenow = new Date().getTime();
o.src="/ValidateCodeDemo/CreateCode";
}
</script>
<body>
This is my JSP page.
<input type="text"/>
<br>
<input type="image" src="/ValidateCodeDemo/CreateCode" name="random" width="80px" height="30px"/>
<!-- 刷新驗證碼 -->
<a href="javaScript:show()">看不清楚,換一張</a>
</body>
</html>