驗證碼是很多系統都需要的,今天搞了一下午終于把驗證碼的功能實現了,可以顯示三種不同類型的驗證碼而不是單獨一種,顯示效果如下圖所示:
* 第一種:簡單驗證碼,4位隨機數字 :
* 第二種:英文字符加數字的驗證碼 :
* 第三種:像鐵路訂票系統一樣的驗證碼,肆+?=21
下面是實現的驗證碼類
Java代碼 ? package?com.base.util;????import?java.awt.Color;??import?java.awt.Font;??import?java.awt.Graphics;??import?java.awt.image.BufferedImage;??import?java.io.ByteArrayInputStream;??import?java.io.ByteArrayOutputStream;??import?java.util.Random;??import?javax.imageio.ImageIO;??import?javax.imageio.stream.ImageOutputStream;????/**??*?驗證碼類,主要生成幾種不同類型的驗證碼???*?第一種:簡單驗證碼,4位隨機數字???*?第二種:英文字符加數字的驗證碼???*?第三種:像鐵路訂票系統一樣的驗證碼,肆+?=21??*???*?@author?李朋飛??*???*/??public?class?VerificationCodeUtil?{??????private?ByteArrayInputStream?image;//?圖像??????private?String?str;//?驗證碼??????private?static?final?int?WIDTH?=?80;??????private?static?final?int?HEIGHT?=?20;????????public?static?void?main(String[]?arg)?{??????????VerificationCodeUtil?vcu?=?VerificationCodeUtil.Instance();??????????System.err.println(vcu.getVerificationCodeValue());??????}????????/**??????*?功能:獲取一個驗證碼類的實例??????*???????*?@return??????*/??????public?static?VerificationCodeUtil?Instance()?{??????????return?new?VerificationCodeUtil();??????}????????private?VerificationCodeUtil()?{??????????BufferedImage?image?=?new?BufferedImage(WIDTH,?HEIGHT,??????????????????BufferedImage.TYPE_INT_RGB);??????????int?randomNum?=?new?Random().nextInt(3);??????????if?(randomNum?==?0)?{??????????????initNumVerificationCode(image);??????????}?else?if?(randomNum?==?1)?{??????????????initLetterAndNumVerificationCode(image);??????????}?else?{??????????????initChinesePlusNumVerificationCode(image);??????????}??????}????????/**??????*?功能:設置第一種驗證碼的屬性??????*/??????public?void?initNumVerificationCode(BufferedImage?image)?{????????????Random?random?=?new?Random();?//?生成隨機類??????????Graphics?g?=?initImage(image,?random);??????????String?sRand?=?"";??????????for?(int?i?=?0;?i?<?4;?i++)?{??????????????String?rand?=?String.valueOf(random.nextInt(10));??????????????sRand?+=?rand;??????????????//?將認證碼顯示到圖象中??????????????g.setColor(new?Color(20?+?random.nextInt(110),?20?+?random??????????????????????.nextInt(110),?20?+?random.nextInt(110)));??????????????//?調用函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成??????????????g.drawString(rand,?13?*?i?+?6,?16);??????????}??????????this.setStr(sRand);/*?賦值驗證碼?*/??????????//?圖象生效??????????g.dispose();??????????this.setImage(drawImage(image));??????}????????/**??????*?功能:設置第二種驗證碼屬性??????*/??????public?void?initLetterAndNumVerificationCode(BufferedImage?image)?{????????????Random?random?=?new?Random();?//?生成隨機類??????????Graphics?g?=?initImage(image,?random);??????????String[]?letter?=?{?"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"?};??????????String?sRand?=?"";??????????for?(int?i?=?0;?i?<?4;?i++)?{??????????????String?tempRand?=?"";??????????????if?(random.nextBoolean())?{??????????????????tempRand?=?String.valueOf(random.nextInt(10));??????????????}?else?{??????????????????tempRand?=?letter[random.nextInt(25)];??????????????????if?(random.nextBoolean())?{//?隨機將該字母變成小寫??????????????????????tempRand?=?tempRand.toLowerCase();??????????????????}??????????????}??????????????sRand?+=?tempRand;??????????????g.setColor(new?Color(20?+?random.nextInt(10),?20?+?random??????????????????????.nextInt(110),?20?+?random.nextInt(110)));??????????????g.drawString(tempRand,?13?*?i?+?6,?16);??????????}??????????this.setStr(sRand);/*?賦值驗證碼?*/??????????g.dispose();?//?圖象生效??????????this.setImage(drawImage(image));??????}????????/**??????*?功能:設置第三種驗證碼屬性?即:肆+?=24??????*/??????public?void?initChinesePlusNumVerificationCode(BufferedImage?image)?{??????????String[]?cn?=?{?"壹",?"貳",?"叁",?"肆",?"伍",?"陸",?"柒",?"捌",?"玖",?"拾"?};??????????Random?random?=?new?Random();?//?生成隨機類??????????Graphics?g?=?initImage(image,?random);??????????int?x?=?random.nextInt(10)?+?1;??????????int?y?=?random.nextInt(30);??????????this.setStr(String.valueOf(y));??????????g.setFont(new?Font("楷體",?Font.PLAIN,?14));//?設定字體??????????g.setColor(new?Color(20?+?random.nextInt(10),?20?+?random.nextInt(110),??????????????????20?+?random.nextInt(110)));??????????g.drawString(cn[x?-?1],?1?*?1?+?6,?16);??????????g.drawString("+",?22,?16);??????????g.drawString("?",?35,?16);??????????g.drawString("=",?48,?16);??????????g.drawString(String.valueOf(x?+?y),?61,?16);??????????g.dispose();?//?圖象生效??????????this.setImage(drawImage(image));????????}????????public?Graphics?initImage(BufferedImage?image,?Random?random)?{??????????Graphics?g?=?image.getGraphics();?//?獲取圖形上下文??????????g.setColor(getRandColor(200,?250));//?設定背景色??????????g.fillRect(0,?0,?WIDTH,?HEIGHT);??????????g.setFont(new?Font("Times?New?Roman",?Font.PLAIN,?14));//?設定字體??????????g.setColor(getRandColor(160,?200));?//?隨機產生165條干擾線,使圖象中的認證碼不易被其它程序探測到??????????for?(int?i?=?0;?i?<?165;?i++)?{??????????????int?x?=?random.nextInt(WIDTH);??????????????int?y?=?random.nextInt(HEIGHT);??????????????int?xl?=?random.nextInt(12);??????????????int?yl?=?random.nextInt(12);??????????????g.drawLine(x,?y,?x?+?xl,?y?+?yl);??????????}??????????return?g;??????}????????public?ByteArrayInputStream?drawImage(BufferedImage?image)?{??????????ByteArrayInputStream?input?=?null;??????????ByteArrayOutputStream?output?=?new?ByteArrayOutputStream();??????????try?{??????????????ImageOutputStream?imageOut?=?ImageIO??????????????????????.createImageOutputStream(output);??????????????ImageIO.write(image,?"JPEG",?imageOut);??????????????imageOut.close();??????????????input?=?new?ByteArrayInputStream(output.toByteArray());??????????}?catch?(Exception?e)?{??????????????System.out.println("驗證碼圖片產生出現錯誤:"?+?e.toString());??????????}??????????return?input;??????}????????/*??????*?功能:給定范圍獲得隨機顏色??????*/??????private?Color?getRandColor(int?fc,?int?bc)?{??????????Random?random?=?new?Random();??????????if?(fc?>?255)??????????????fc?=?255;??????????if?(bc?>?255)??????????????bc?=?255;??????????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);??????}????????/**??????*?功能:獲取驗證碼的字符串值??????*???????*?@return??????*/??????public?String?getVerificationCodeValue()?{??????????return?this.getStr();??????}????????/**??????*?功能:取得驗證碼圖片??????*???????*?@return??????*/??????public?ByteArrayInputStream?getImage()?{??????????return?this.image;??????}????????public?String?getStr()?{??????????return?str;??????}????????public?void?setStr(String?str)?{??????????this.str?=?str;??????}????????public?void?setImage(ByteArrayInputStream?image)?{??????????this.image?=?image;??????}??}??
struts2中獲得驗證碼:
Java代碼 ? /**??*?功能:打開login.jsp的時候獲得隨機的驗證碼圖片??*???*?@return??*/??public?String?getRandomPictrue()?{??????VerificationCodeUtil?vcu?=?VerificationCodeUtil.Instance();??????this.setInputStream(vcu.getImage());????? ActionContext.getContext().getSession().put("random",?vcu.getVerificationCodeValue());//?取得隨機字符串放入HttpSession??????return?SUCCESS;????}??
另外前臺jsp頁面
Java代碼 ? ??<script?type="text/javascript">?????????function?changeValidateCode(obj)?{????????????????//獲取當前的時間作為參數,無具體意義?????????????var?timenow?=?new?Date().getTime();????????????????//每次請求需要一個不同的參數,否則可能會返回同樣的驗證碼?????????????//這和瀏覽器的緩存機制有關系,也可以把頁面設置為不緩存,這樣就不用這個參數了。?????????????obj.src="getRandomPictrue?d="+timenow;?????????}?????</script>??<tr>??????????????????<td?height="24"?valign="bottom"><div?align="right"><span?class="STYLE3">驗證碼</span></div></td>??????????????????<td?width="10"?valign="bottom"> </td>??????????????????<td?width="52"?height="24"?valign="bottom"><input?type="text"??maxlength=4?name="yzm"?id="textfield3"?style="width:50px;?height:17px;?background-color:#87adbf;?border:solid?1px?#153966;?font-size:12px;?color:#283439;?"></td>??????????????????<td?width="92"?valign="bottom"><div?align="center"><img?src="getRandomPictrue.action"?width="80"?height="20"?οnclick="changeValidateCode(this)"></div></td>????????????????</tr>???
另外,在登錄的時候,后臺驗證驗證碼是否輸入正確
Java代碼 ? public?String?userLogin()?{??????????String?yanzhengma?=?this.getYzm().toLowerCase();//將驗證碼字符串全部轉換成小寫??????????String?random?=?getSessionAttribute("random").toString().toLowerCase();????????????????if(!yanzhengma.equals(random)){??????????????this.setRequestAttribute("errorMessage",?"驗證碼錯誤,請核實后重新輸入");??????????????return?INPUT;??????????}??????????else{??????????????UserModel?user?=?getUserService().loginJudge(getUserName(),??????????????????????getUserPass());??????????????if?(user?!=?null)?{??????????????????getSession().setAttribute("user",?user);??????????????????getSession().setAttribute("userId",?user.getUserId());??????????????????List<PermissionModel>?treeList?=?userService.getTree(user??????????????????????????.getUserId());??????????????????getRequest().setAttribute("treeList",?treeList);??????????????????this.setRequestAttribute("username",?user.getUserName());??????????????????user.setLastLoginTime(DateUtil.getCurrentTimestamp());??????????????????if?(userService.addUser(user))?{??????????????????????logger.info(getUserName()?+?"登錄成功");??????????????????????return?SUCCESS;??????????????????}?else?{??????????????????????logger.info(getUserName()?+?"登錄失敗,失敗原因,更新lastLoginTime失敗");??????????????????????this.setRequestAttribute("errorMessage",?"服務器hold不住啦,請稍后重新登錄");??????????????????????return?INPUT;??????????????????}??????????????}?else?{??????????????????logger.info(getUserName()?+?"登錄失敗,用戶名或者密碼不正確");??????????????????this.setRequestAttribute("errorMessage",?"登錄失敗,用戶名或者密碼不正確");??????????????????return?INPUT;??????????????}??????????}????????????????}?? ? 分享到: package com.base.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
/**
?* 驗證碼類,主要生成幾種不同類型的驗證碼
?* 第一種:簡單驗證碼,4位隨機數字
?* 第二種:英文字符加數字的驗證碼
?* 第三種:像鐵路訂票系統一樣的驗證碼,肆+?=21
?*
?* @author 李朋飛
?*
?*/
public class VerificationCodeUtil {
?? ?private ByteArrayInputStream image;// 圖像
?? ?private String str;// 驗證碼
?? ?private static final int WIDTH = 80;
?? ?private static final int HEIGHT = 20;
?? ?public static void main(String[] arg) {
?? ??? ?VerificationCodeUtil vcu = VerificationCodeUtil.Instance();
?? ??? ?System.err.println(vcu.getVerificationCodeValue());
?? ?}
?? ?/**
?? ? * 功能:獲取一個驗證碼類的實例
?? ? *
?? ? * @return
?? ? */
?? ?public static VerificationCodeUtil Instance() {
?? ??? ?return new VerificationCodeUtil();
?? ?}
?? ?private VerificationCodeUtil() {
?? ??? ?BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
?? ??? ??? ??? ?BufferedImage.TYPE_INT_RGB);
?? ??? ?int randomNum = new Random().nextInt(3);
?? ??? ?if (randomNum == 0) {
?? ??? ??? ?initNumVerificationCode(image);
?? ??? ?} else if (randomNum == 1) {
?? ??? ??? ?initLetterAndNumVerificationCode(image);
?? ??? ?} else {
?? ??? ??? ?initChinesePlusNumVerificationCode(image);
?? ??? ?}
?? ?}
?? ?/**
?? ? * 功能:設置第一種驗證碼的屬性
?? ? */
?? ?public void initNumVerificationCode(BufferedImage image) {
?? ??? ?Random random = new Random(); // 生成隨機類
?? ??? ?Graphics g = initImage(image, random);
?? ??? ?String sRand = "";
?? ??? ?for (int i = 0; i < 4; i++) {
?? ??? ??? ?String rand = String.valueOf(random.nextInt(10));
?? ??? ??? ?sRand += rand;
?? ??? ??? ?// 將認證碼顯示到圖象中
?? ??? ??? ?g.setColor(new Color(20 + random.nextInt(110), 20 + random
?? ??? ??? ??? ??? ?.nextInt(110), 20 + random.nextInt(110)));
?? ??? ??? ?// 調用函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成
?? ??? ??? ?g.drawString(rand, 13 * i + 6, 16);
?? ??? ?}
?? ??? ?this.setStr(sRand);/* 賦值驗證碼 */
?? ??? ?// 圖象生效
?? ??? ?g.dispose();
?? ??? ?this.setImage(drawImage(image));
?? ?}
?? ?/**
?? ? * 功能:設置第二種驗證碼屬性
?? ? */
?? ?public void initLetterAndNumVerificationCode(BufferedImage image) {
?? ??? ?Random random = new Random(); // 生成隨機類
?? ??? ?Graphics g = initImage(image, random);
?? ??? ?String[] letter = { "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" };
?? ??? ?String sRand = "";
?? ??? ?for (int i = 0; i < 4; i++) {
?? ??? ??? ?String tempRand = "";
?? ??? ??? ?if (random.nextBoolean()) {
?? ??? ??? ??? ?tempRand = String.valueOf(random.nextInt(10));
?? ??? ??? ?} else {
?? ??? ??? ??? ?tempRand = letter[random.nextInt(25)];
?? ??? ??? ??? ?if (random.nextBoolean()) {// 隨機將該字母變成小寫
?? ??? ??? ??? ??? ?tempRand = tempRand.toLowerCase();
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?sRand += tempRand;
?? ??? ??? ?g.setColor(new Color(20 + random.nextInt(10), 20 + random
?? ??? ??? ??? ??? ?.nextInt(110), 20 + random.nextInt(110)));
?? ??? ??? ?g.drawString(tempRand, 13 * i + 6, 16);
?? ??? ?}
?? ??? ?this.setStr(sRand);/* 賦值驗證碼 */
?? ??? ?g.dispose(); // 圖象生效
?? ??? ?this.setImage(drawImage(image));
?? ?}
?? ?/**
?? ? * 功能:設置第三種驗證碼屬性 即:肆+?=24
?? ? */
?? ?public void initChinesePlusNumVerificationCode(BufferedImage image) {
?? ??? ?String[] cn = { "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖", "拾" };
?? ??? ?Random random = new Random(); // 生成隨機類
?? ??? ?Graphics g = initImage(image, random);
?? ??? ?int x = random.nextInt(10) + 1;
?? ??? ?int y = random.nextInt(30);
?? ??? ?this.setStr(String.valueOf(y));
?? ??? ?g.setFont(new Font("楷體", Font.PLAIN, 14));// 設定字體
?? ??? ?g.setColor(new Color(20 + random.nextInt(10), 20 + random.nextInt(110),
?? ??? ??? ??? ?20 + random.nextInt(110)));
?? ??? ?g.drawString(cn[x - 1], 1 * 1 + 6, 16);
?? ??? ?g.drawString("+", 22, 16);
?? ??? ?g.drawString("?", 35, 16);
?? ??? ?g.drawString("=", 48, 16);
?? ??? ?g.drawString(String.valueOf(x + y), 61, 16);
?? ??? ?g.dispose(); // 圖象生效
?? ??? ?this.setImage(drawImage(image));
?? ?}
?? ?public Graphics initImage(BufferedImage image, Random random) {
?? ??? ?Graphics g = image.getGraphics(); // 獲取圖形上下文
?? ??? ?g.setColor(getRandColor(200, 250));// 設定背景色
?? ??? ?g.fillRect(0, 0, WIDTH, HEIGHT);
?? ??? ?g.setFont(new Font("Times New Roman", Font.PLAIN, 14));// 設定字體
?? ??? ?g.setColor(getRandColor(160, 200)); // 隨機產生165條干擾線,使圖象中的認證碼不易被其它程序探測到
?? ??? ?for (int i = 0; i < 165; i++) {
?? ??? ??? ?int x = random.nextInt(WIDTH);
?? ??? ??? ?int y = random.nextInt(HEIGHT);
?? ??? ??? ?int xl = random.nextInt(12);
?? ??? ??? ?int yl = random.nextInt(12);
?? ??? ??? ?g.drawLine(x, y, x + xl, y + yl);
?? ??? ?}
?? ??? ?return g;
?? ?}
?? ?public ByteArrayInputStream drawImage(BufferedImage image) {
?? ??? ?ByteArrayInputStream input = null;
?? ??? ?ByteArrayOutputStream output = new ByteArrayOutputStream();
?? ??? ?try {
?? ??? ??? ?ImageOutputStream imageOut = ImageIO
?? ??? ??? ??? ??? ?.createImageOutputStream(output);
?? ??? ??? ?ImageIO.write(image, "JPEG", imageOut);
?? ??? ??? ?imageOut.close();
?? ??? ??? ?input = new ByteArrayInputStream(output.toByteArray());
?? ??? ?} catch (Exception e) {
?? ??? ??? ?System.out.println("驗證碼圖片產生出現錯誤:" + e.toString());
?? ??? ?}
?? ??? ?return input;
?? ?}
?? ?/*
?? ? * 功能:給定范圍獲得隨機顏色
?? ? */
?? ?private Color getRandColor(int fc, int bc) {
?? ??? ?Random random = new Random();
?? ??? ?if (fc > 255)
?? ??? ??? ?fc = 255;
?? ??? ?if (bc > 255)
?? ??? ??? ?bc = 255;
?? ??? ?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);
?? ?}
?? ?/**
?? ? * 功能:獲取驗證碼的字符串值
?? ? *
?? ? * @return
?? ? */
?? ?public String getVerificationCodeValue() {
?? ??? ?return this.getStr();
?? ?}
?? ?/**
?? ? * 功能:取得驗證碼圖片
?? ? *
?? ? * @return
?? ? */
?? ?public ByteArrayInputStream getImage() {
?? ??? ?return this.image;
?? ?}
?? ?public String getStr() {
?? ??? ?return str;
?? ?}
?? ?public void setStr(String str) {
?? ??? ?this.str = str;
?? ?}
?? ?public void setImage(ByteArrayInputStream image) {
?? ??? ?this.image = image;
?? ?}
}
轉載于:https://www.cnblogs.com/lanxuezaipiao/archive/2012/07/09/2583636.html
總結
以上是生活随笔為你收集整理的基于struts2+hibernate+spring(ssh2)的登录验证码的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。