Java如何實(shí)現(xiàn)驗(yàn)證碼驗(yàn)證功能
Java如何實(shí)現(xiàn)驗(yàn)證碼驗(yàn)證功能呢?日常生活中,驗(yàn)證碼隨處可見,他可以在一定程度上保護(hù)賬號(hào)安全,那么他是怎么實(shí)現(xiàn)的呢?
Java實(shí)現(xiàn)驗(yàn)證碼驗(yàn)證功能其實(shí)非常簡單:用到了一個(gè)Graphics類在畫板上繪制字母,隨機(jī)選取一定數(shù)量的字母隨機(jī)生成,然后在畫板上隨機(jī)生成幾條干擾線。
首先,寫一個(gè)驗(yàn)證碼生成幫助類,用來繪制隨機(jī)字母:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public final class GraphicHelper {
/**
* 以字符串形式返回生成的驗(yàn)證碼,同時(shí)輸出一個(gè)圖片
*
* @param width
* 圖片的寬度
* @param height
* 圖片的高度
* @param imgType
* 圖片的類型
* @param output
* 圖片的輸出流(圖片將輸出到這個(gè)流中)
* @return 返回所生成的驗(yàn)證碼(字符串)
*/
public static String create(final int width, final int height, final String imgType, OutputStream output) {
StringBuffer sb = new StringBuffer();
Random random = new Random();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphic = image.getGraphics();
graphic.setColor(Color.getColor("F8F8F8"));
graphic.fillRect(0, 0, width, height);
Color[] colors = new Color[] { Color.BLUE, Color.GRAY, Color.GREEN, Color.RED, Color.BLACK, Color.ORANGE,
Color.CYAN };
// 在 "畫板"上生成干擾線條 ( 50 是線條個(gè)數(shù))
for (int i = 0; i < 50; i++) {
graphic.setColor(colors[random.nextInt(colors.length)]);
final int x = random.nextInt(width);
final int y = random.nextInt(height);
final int w = random.nextInt(20);
final int h = random.nextInt(20);
final int signA = random.nextBoolean() ? 1 : -1;
final int signB = random.nextBoolean() ? 1 : -1;
graphic.drawLine(x, y, x + w * signA, y + h * signB);
}
// 在 "畫板"上繪制字母
graphic.setFont(new Font("Comic Sans MS", Font.BOLD, 30));
for (int i = 0; i < 6; i++) {
final int temp = random.nextInt(26) + 97;
String s = String.valueOf((char) temp);
sb.append(s);
graphic.setColor(colors[random.nextInt(colors.length)]);
graphic.drawString(s, i * (width / 6), height - (height / 3));
}
graphic.dispose();
try {
ImageIO.write(image, imgType, output);
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
接著,創(chuàng)建一個(gè)servlet,用來固定圖片大小,以及處理驗(yàn)證碼的使用場景,以及捕獲頁面生成的驗(yàn)證碼(捕獲到的二維碼與用戶輸入的驗(yàn)證碼一致才能通過)。
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet(urlPatterns = "/verify/regist.do" )
public class VerifyCodeServlet extends HttpServlet {
private static final long serialVersionUID = 3398560501558431737L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 獲得 當(dāng)前請求 對(duì)應(yīng)的 會(huì)話對(duì)象
HttpSession session = request.getSession();
// 從請求中獲得 URI ( 統(tǒng)一資源標(biāo)識(shí)符 )
String uri = request.getRequestURI();
System.out.println("hello : " + uri);
final int width = 180; // 圖片寬度
final int height = 40; // 圖片高度
final String imgType = "jpeg"; // 指定圖片格式 (不是指MIME類型)
final OutputStream output = response.getOutputStream();
// 獲得可以向客戶端返回圖片的輸出流
// (字節(jié)流)
// 創(chuàng)建驗(yàn)證碼圖片并返回圖片上的字符串
String code = GraphicHelper.create(width, height, imgType, output);
System.out.println("驗(yàn)證碼內(nèi)容: " + code);
// 建立 uri 和 相應(yīng)的 驗(yàn)證碼 的關(guān)聯(lián) ( 存儲(chǔ)到當(dāng)前會(huì)話對(duì)象的屬性中 )
session.setAttribute(uri, code);
System.out.println(session.getAttribute(uri));
}
}
接著寫一個(gè)HTML注冊頁面用來檢驗(yàn)一下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>注冊</title>
<link rel="stylesheet" href="styles/general.css" >
<link rel="stylesheet" href="styles/cell.css">
<link rel="stylesheet" href="styles/form.css">
<script type="text/javascript" src="js/ref.js"></script>
<style type="text/css" >
.logo-container {
margin-top: 50px ;
}
.logo-container img {
width: 100px ;
}
.message-container {
height: 80px ;
}
.link-container {
height: 40px ;
line-height: 40px ;
}
.link-container a {
text-decoration: none ;
}
</style>
</head>
<body>
<div class="container form-container">
<form action="/wendao/regist.do" method="post">
<div class="form"> <!-- 注冊表單開始 -->
<div class="form-row">
<span class="cell-1">
<i class="fa fa-user"></i>
</span>
<span class="cell-11" style="text-align: left;">
<input type="text" name="username" placeholder="請輸入用戶名">
</span>
</div>
<div class="form-row">
<span class="cell-1">
<i class="fa fa-key"></i>
</span>
<span class="cell-11" style="text-align: left;">
<input type="password" name="password" placeholder="請輸入密碼">
</span>
</div>
<div class="form-row">
<span class="cell-1">
<i class="fa fa-keyboard-o"></i>
</span>
<span class="cell-11" style="text-align: left;">
<input type="password" name="confirm" placeholder="請確認(rèn)密碼">
</span>
</div>
<div class="form-row">
<span class="cell-7">
<input type="text" name="verifyCode" placeholder="請輸入驗(yàn)證碼">
</span>
<span class="cell-5" style="text-align: center;">
<img src="/demo/verify/regist.do" onclick="myRefersh(this)">
</span>
</div>
<div class="form-row" style="border: none;">
<span class="cell-6" style="text-align: left">
<input type="reset" value="重置">
</span>
<span class="cell-6" style="text-align:right;">
<input type="submit" value="注冊">
</span>
</div>
</div> <!-- 注冊表單結(jié)束 -->
</form>
</div>
</body>
</html>
效果如下圖:

當(dāng)點(diǎn)擊刷新頁面的時(shí)候,驗(yàn)證碼也會(huì)隨著變化,但我們看不清驗(yàn)證碼時(shí),只要點(diǎn)擊驗(yàn)證碼就會(huì)刷新,這樣局部的刷新可以用JavaScript來實(shí)現(xiàn)。
在<img src="/demo/verify/regist.do">中,添加一個(gè)問號(hào)和一串后綴數(shù)字,當(dāng)刷新時(shí)讓后綴數(shù)字不斷改變,那么形成的驗(yàn)證碼也會(huì)不斷變化,我們可以采用的一種辦法是后綴數(shù)字用date代替,date獲取本機(jī)時(shí)間,時(shí)間是隨時(shí)變的,這樣就保證了刷新驗(yàn)證碼可以隨時(shí)變化。
代碼如下:
function myRefersh( e ) {
const source = e.src ; // 獲得原來的 src 中的內(nèi)容
//console.log( "source : " + source ) ;
var index = source.indexOf( "?" ) ; // 從 source 中尋找 ? 第一次出現(xiàn)的位置 (如果不存在則返回 -1 )
//console.log( "index : " + index ) ;
if( index > -1 ) { // 如果找到了 ? 就進(jìn)入內(nèi)部
var s = source.substring( 0 , index ) ; // 從 source 中截取 index 之前的內(nèi)容 ( index 以及 index 之后的內(nèi)容都被舍棄 )
//console.log( "s : " + s ) ;
var date = new Date(); // 創(chuàng)建一個(gè) Date 對(duì)象的 一個(gè) 實(shí)例
var time = date.getTime() ; // 從 新創(chuàng)建的 Date 對(duì)象的實(shí)例中獲得該時(shí)間對(duì)應(yīng)毫秒值
e.src = s + "?time=" + time ; // 將 加了 尾巴 的 地址 重新放入到 src 上
//console.log( e.src ) ;
} else {
var date = new Date();
e.src = source + "?time=" + date.getTime();
}
}
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- java登錄驗(yàn)證碼實(shí)現(xiàn)代碼
- java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼
- Java實(shí)現(xiàn)驗(yàn)證碼具體代碼
- Java 隨機(jī)生成驗(yàn)證碼(支持大小寫字母、數(shù)字、隨機(jī)字體)的實(shí)例
- Java隨機(jī)生成手機(jī)短信驗(yàn)證碼的方法
- JAVA實(shí)現(xiàn)利用第三方平臺(tái)發(fā)送短信驗(yàn)證碼
- Java實(shí)現(xiàn)仿淘寶滑動(dòng)驗(yàn)證碼研究代碼詳解
- Java Web開發(fā)之圖形驗(yàn)證碼的生成與使用方法
- java實(shí)現(xiàn)驗(yàn)證碼類生成中文驗(yàn)證碼
- java生成圖片驗(yàn)證碼示例程序
相關(guān)文章
深入解析Java編程中的boolean對(duì)象的運(yùn)用
這篇文章主要介紹了Java編程中的boolean對(duì)象的運(yùn)用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-10-10
idea?springBoot項(xiàng)目自動(dòng)注入mapper為空報(bào)錯(cuò)的解決方法
這篇文章主要介紹了idea?springBoot項(xiàng)目自動(dòng)注入mapper為空報(bào)錯(cuò)的解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
Spring boot 路徑映射的實(shí)現(xiàn)
這篇文章主要介紹了spring boot 路徑映射的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
java實(shí)現(xiàn)切割wav音頻文件的方法詳解【附外部jar包下載】
這篇文章主要介紹了java實(shí)現(xiàn)切割wav音頻文件的方法,結(jié)合實(shí)例形式詳細(xì)分析了java切割wav音頻文件的相關(guān)原理、操作技巧與注意事項(xiàng),并附帶外部jar包供讀者下載,需要的朋友可以參考下2019-05-05

