一、主要功能:
1、支援純數字、大寫字母、小寫字母,及兩兩混合或三者混合類型驗證碼;
2、支援自訂特殊字元排除(如0oOi1jI);
3、支援圖片及文字兩種類型驗證碼;
4、支援自訂驗證碼圖片大小;
5、支援自訂幹擾線條數;
6、支援自訂及隨機定義圖片、文字、幹擾線顏色;
其他:樣本頁面提供了<iframe>和<img>兩種頁面顯示驗證碼的方式。
a、僅阿拉伯數字
二、主要代碼
1.index.jsp
<%@ page language="java" import="java.util.*" 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>
<title><%=basePath%></title>
</head>
<script type="text/javascript">
var req;
//提交留言
function pubMsg(){
msgTitle = document.msgForm.msgTitle.value;
msgContent = document.msgForm.msgContent.value;
verifyCode = document.msgForm.verifyCode.value;
//檢查輸入內容格式
if(msgTitle.length<5||msgContent.length<5){
alert("標題和內容不能少於5個字元");
return;
}
if(verifyCode.length==0){
alert("請輸入驗證碼");
return;
}
//獲得 XMLHttpRequest對象
if(window.XMLHttpRequest)
req=new XMLHttpRequest();
else if(window.ActiveXObject)
req=new ActiveXObject("Microsoft.XMLHTTP");
//提交請求
if(req){
req.onreadystatechange=callBack;//指定伺服器響應結果處理函數(注意僅函數名無括弧)
url="<%=path%>/servlet/PubMsgServlet?msgTitle="+msgTitle+"&msgContent="+msgContent+"&verifyCode="+verifyCode;
req.open("GET",url,false);
req.send();
}
}
//伺服器響應結果處理函數
function callBack(){
if(req.readyState==4){
if(req.status==200){
next=req.responseText;//獲得伺服器處理結果
if(next=="this"){
alert("驗證碼不正確,請重新輸入");
verifyCodeFrame.location.reload();//重新整理驗證碼
}else{
document.msgForm.msgTitle.value="";
document.msgForm.msgContent.value="";
window.location=next;//跳轉頁面
}
}else{
alert(req.status+":"+req.statusText);
}
}
document.msgForm.verifyCode.value="";
}
//更換驗證碼
function changeVerifyCode(){
//1、如果用<iframe>實現,則重新載入<iframe>的內容
//verifyCodeFrame.location.reload();
//2、如果用<img>實現,則修改<img src=url>的url
//這裡有一個小技巧,如果給url賦相同的值,瀏覽器不會重新發出請求,因此用js產生一個即時毫秒數做url中的參數
t=new Date().getTime();
document.msgForm.verifyCodeImg.src="<%=path%>/servlet/VerifyCodeServlet?t="+t;
}
</script>
<body>
<form name="msgForm" action="" method="post">
<table border=0>
<tr>
<td>標題:</td>
<td><input name="msgTitle" size="65" /></td>
</tr>
<tr>
<td>內容:</td>
<td><textarea name="msgContent" rows="10" cols="64"></textarea></td>
</tr>
<tr>
<td>驗證碼:</td>
<td>
<input name="verifyCode" style="height: 29px; width =70px; font-size: 25px" />
<!-- 以下:兩種顯示驗證碼的方式 -->
<!-- 1、採用<iframe>實現 -->
<!--
<iframe name="verifyCodeFrame" src="<%=path + "/servlet/VerifyCodeServlet"%>"
width="100" height="30" frameborder=0 align="top" marginheight=0 marginwidth=0 scrolling=no></iframe>
-->
<!-- 2、採用<img>實現 -->
<img name="verifyCodeImg" src="<%=path%>/servlet/VerifyCodeServlet" style="cursor:hand" align="align" onClick="changeVerifyCode()" />
<!-- 以上:兩種顯示驗證碼的方式 -->
<font style="color: blue;"><a href="javascript:changeVerifyCode()">看不清?</a> </font>
<input type="button" value=" 發表留言 " onClick="pubMsg()" />
</td>
</tr>
</table>
</form>
</body>
</html>
2.org.javachina.util.VerifyCode.java
package org.javachina.util;
import java.util.Random;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
/**
* 驗證碼產生器類,可產生數字、大寫、小寫字母及三者混合類型的驗證碼。 支援自訂驗證碼字元數量; 支援自訂驗證碼圖片的大小; 支援自訂需排除的特殊字元;
* 支援自訂幹擾線的數量; 支援自訂驗證碼圖文顏色
*
* @author org.javachina
* @version 1.01
*/
public class VerifyCode {
/**
* 驗證碼類型為僅數字 0~9
*/
public static final int TYPE_NUM_ONLY = 0;
/**
* 驗證碼類型為僅字母,即大寫、小寫字母混合
*/
public static final int TYPE_LETTER_ONLY = 1;
/**
* 驗證碼類型為數字、大寫字母、小寫字母混合
*/
public static final int TYPE_ALL_MIXED = 2;
/**
* 驗證碼類型為數字、大寫字母混合
*/
public static final int TYPE_NUM_UPPER = 3;
/**
* 驗證碼類型為數字、小寫字母混合
*/
public static final int TYPE_NUM_LOWER = 4;
/**
* 驗證碼類型為僅大寫字母
*/
public static final int TYPE_UPPER_ONLY = 5;
/**
* 驗證碼類型為僅小寫字母
*/
public static final int TYPE_LOWER_ONLY = 6;
private VerifyCode() {
}
/**
* 產生驗證碼字串
*
* @param type
* 驗證碼類型,參見本類的靜態屬性
* @param length
* 驗證碼長度,大於0的整數
* @param exChars
* 需排除的特殊字元(僅對數字、字母混合型驗證碼有效,無需排除則為 null)
* @return 驗證碼字串
*/
public static String generateTextCode(int type, int length, String exChars) {
if (length <= 0)
return "";
StringBuffer code = new StringBuffer();
int i = 0;
Random r = new Random();
switch (type) {
// 僅數字
case TYPE_NUM_ONLY:
while (i < length) {
int t = r.nextInt(10);
if (exChars == null || exChars.indexOf(t + "") < 0) {// 排除特殊字元
code.append(t);
i++;
}
}
break;
// 僅字母(即大寫字母、小寫字母混合)
case TYPE_LETTER_ONLY:
while (i < length) {
int t = r.nextInt(123);
if ((t >= 97 || (t >= 65 && t <= 90)) && (exChars == null || exChars.indexOf((char) t) < 0)) {
code.append((char) t);
i++;
}
}
break;
// 數字、大寫字母、小寫字母混合
case TYPE_ALL_MIXED:
while (i < length) {
int t = r.nextInt(123);
if ((t >= 97 || (t >= 65 && t <= 90) || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {
code.append((char) t);
i++;
}
}
break;
// 數字、大寫字母混合
case TYPE_NUM_UPPER:
while (i < length) {
int t = r.nextInt(91);
if ((t >= 65 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {
code.append((char) t);
i++;
}
}
break;
// 數字、小寫字母混合
case TYPE_NUM_LOWER:
while (i < length) {
int t = r.nextInt(123);
if ((t >= 97 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {
code.append((char) t);
i++;
}
}
break;
// 僅大寫字母
case TYPE_UPPER_ONLY:
while (i < length) {
int t = r.nextInt(91);
if ((t >= 65) && (exChars == null || exChars.indexOf((char) t) < 0)) {
code.append((char) t);
i++;
}
}
break;
// 僅小寫字母
case TYPE_LOWER_ONLY:
while (i < length) {
int t = r.nextInt(123);
if ((t >= 97) && (exChars == null || exChars.indexOf((char) t) < 0)) {
code.append((char) t);
i++;
}
}
break;
}
return code.toString();
}
/**
* 已有驗證碼,產生驗證碼圖片
*
* @param textCode
* 文本驗證碼
* @param width
* 圖片寬度
* @param height
* 圖片高度
* @param interLine
* 圖片中幹擾線的條數
* @param randomLocation
* 每個字元的高低位置是否隨機
* @param backColor
* 圖片顏色,若為null,則採用隨機顏色
* @param foreColor
* 字型顏色,若為null,則採用隨機顏色
* @param lineColor
* 幹擾線顏色,若為null,則採用隨機顏色
* @return 圖片緩衝對象
*/
public static BufferedImage generateImageCode(String textCode, int width, int height, int interLine, boolean randomLocation, Color backColor,
Color foreColor, Color lineColor) {
BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = bim.getGraphics();
// 畫背景圖
g.setColor(backColor == null ? getRandomColor() : backColor);
g.fillRect(0, 0, width, height);
// 畫幹擾線
Random r = new Random();
if (interLine > 0) {
int x = 0, y = 0, x1 = width, y1 = 0;
for (int i = 0; i < interLine; i++) {
g.setColor(lineColor == null ? getRandomColor() : lineColor);
y = r.nextInt(height);
y1 = r.nextInt(height);
g.drawLine(x, y, x1, y1);
}
}
// 寫驗證碼
// g.setColor(getRandomColor());
// g.setColor(isSimpleColor?Color.BLACK:Color.WHITE);
// 字型大小為圖片高度的80%
int fsize = (int) (height * 0.8);
int fx = height - fsize;
int fy = fsize;
g.setFont(new Font(Font.DIALOG, Font.PLAIN, fsize));
// 寫驗證碼字元
for (int i = 0; i < textCode.length(); i++) {
fy = randomLocation ? (int) ((Math.random() * 0.3 + 0.6) * height) : fy;// 每個字元高低是否隨機
g.setColor(foreColor == null ? getRandomColor() : foreColor);
g.drawString(textCode.charAt(i) + "", fx, fy);
fx += fsize * 0.9;
}
g.dispose();
return bim;
}
/**
* 產生圖片驗證碼
*
* @param type
* 驗證碼類型,參見本類的靜態屬性
* @param length
* 驗證碼字元長度,大於0的整數
* @param exChars
* 需排除的特殊字元
* @param width
* 圖片寬度
* @param height
* 圖片高度
* @param interLine
* 圖片中幹擾線的條數
* @param randomLocation
* 每個字元的高低位置是否隨機
* @param backColor
* 圖片顏色,若為null,則採用隨機顏色
* @param foreColor
* 字型顏色,若為null,則採用隨機顏色
* @param lineColor
* 幹擾線顏色,若為null,則採用隨機顏色
* @return 圖片緩衝對象
*/
public static BufferedImage generateImageCode(int type, int length, String exChars, int width, int height, int interLine, boolean randomLocation,
Color backColor, Color foreColor, Color lineColor) {
String textCode = generateTextCode(type, length, exChars);
BufferedImage bim = generateImageCode(textCode, width, height, interLine, randomLocation, backColor, foreColor, lineColor);
return bim;
}
/**
* 產生隨機顏色
*
* @return
*/
private static Color getRandomColor() {
Random r = new Random();
Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
return c;
}
public static void main(String[] args) {
}
}
3.org.javachina.servlet.VerifyCodeServlet.java
package org.javachina.servlet;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.javachina.util.VerifyCode;
public class VerifyCodeServlet extends HttpServlet {
public VerifyCodeServlet() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 設定瀏覽器不緩衝本頁
response.setHeader("Cache-Control", "no-cache");
// 產生驗證碼,寫入使用者session
String verifyCode = VerifyCode.generateTextCode(VerifyCode.TYPE_UPPER_ONLY, 4, null);
request.getSession().setAttribute("verifyCode", verifyCode);
// 輸出驗證碼給用戶端
response.setContentType("image/jpeg");
BufferedImage bim = VerifyCode.generateImageCode(verifyCode, 60, 20, 3, true, Color.WHITE, Color.BLACK, null);
ImageIO.write(bim, "JPEG", response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
public void init() throws ServletException {
}
}
4.org.javachina.servlet.PubMsgServlet.java
package org.javachina.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PubMsgServlet extends HttpServlet {
public PubMsgServlet() {
super();
}
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 得到留言標題、內容及使用者輸入的驗證碼
String msgTitle = request.getParameter("msgTitle");
String msgContent = request.getParameter("msgContent");
String verifyCode = request.getParameter("verifyCode");
// 取session中的正確驗證碼
String legalCode = null;
if (request.getSession().getAttribute("verifyCode") != null)
legalCode = (String) (request.getSession().getAttribute("verifyCode"));
String next;
// 比較session中的驗證碼與使用者輸入是否一致(這裡忽略了大小寫)
if (verifyCode != null && verifyCode.equalsIgnoreCase(legalCode)) {
/*
* 儲存留言內容(省略)
*/
// 指定下一個URL
next = request.getContextPath() + "/ok.jsp";
} else
next = "this";
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
out.print(next);
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
public void init() throws ServletException {
}
}
5. ok.jsp
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
您的留言已提交!<input type="button" value=" OK " onClick="window.history.go(-1)"/><br>
</body>
</html>
6.修改web.xml 添加如下內容:
<servlet>
<servlet-name>VerifyCodeServlet</servlet-name>
<servlet-class>org.javachina.servlet.VerifyCodeServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>PubMsgServlet</servlet-name>
<servlet-class>org.javachina.servlet.PubMsgServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>VerifyCodeServlet</servlet-name>
<url-pattern>/servlet/VerifyCodeServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PubMsgServlet</servlet-name>
<url-pattern>/servlet/PubMsgServlet</url-pattern>
</servlet-mapping>
轉載地址: http://www.java3z.com/cwbwebhome/article/article3/3468.html?id=2132