在JavaWeb項目中利用demo實現一個驗證碼功能?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
DEMO 目標功能
開工
頁面:demo1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>驗證示例</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<style type="text/css">
img {
width: 87px;
height: 33px;
border: 1px solid gray;
}
#msg {color: red;} /* 后臺返回的驗證信息顯示為紅色 */
</style>
</head>
<body>
<form action="${pageContext.request.contextPath}/check" method="post" enctype="application/x-www-form-urlencoded">
驗證碼:<input type="text" name="code" size="4" maxlength="4" id="code" />
<img id="code-img" src="" alt="驗證碼" />
<a href="javascript:void(0)" rel="external nofollow" id="changeCode">看不清?換一張</a> <br/><br/>
<input type="submit" value="驗證"/> <span id="msg">${msg}</span>
</form>
</body>
</html>說明:
"看不清?換一張" 的 href 屬性寫成 javascript:void(0) 是為了防止頁面刷新,這里的更換功能交給 AJAX 異步完成。
JavaScript 工具:util.js(為啥用原生 JS?任性唄~哈)
/**
* 獲取 XMLHttpRequest Object
* @returns XMLHttpRequest Object
*/
function getXHR() {
var xmlHttp;
try { // Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) { // Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Sorry, 您的瀏覽器不支持 AJAX!");
return false;
}
}
}
return xmlHttp;
}頁面中的 JavaScript 代碼
<script type="text/javascript" src="${pageContext.request.contextPath}/js/util.js"></script>
<script type="text/javascript">
var xhr = getXHR(); // 獲得 XMLHttpRequest 對象
// 頁面加載時加載驗證碼,但驗證碼初始為隱藏狀態
window.onload=function() {
// 為 onreadystatechange 事件注冊回調函數。由于 xhr 為全局變量,所以注冊后就不用管啦
xhr.onreadystatechange=function() {
if(xhr.readyState==4 && xhr.status==200) {
document.getElementById('code-img').src="data:image/png;base64,"+xhr.responseText;
}
}
xhr.open("GET","${pageContext.request.contextPath}/captcha/code",true);
xhr.send(null);
}
// 驗證碼輸入框獲得焦點時,驗證碼狀態更改為顯示
document.getElementById('code').onfocus=function() {
document.getElementById('code-img').style.display="inline";
}
// 異步請求,更換驗證碼
document.getElementById('changeCode').onclick=function() {
xhr.open("GET","${pageContext.request.contextPath}/captcha/code",true);
xhr.send(null);
}
</script>生成驗證碼的 CaptchaCodeServlet.java
package com.leo.web.captcha;
import java.io.IOException;
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 com.leo.util.ImageUtil;
import cn.dsna.util.images.ValidateCode;
@WebServlet("/captcha/code")
public class CaptchaCodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// 生成驗證碼(構造參數分別代表:寬度,高度,字符數,干擾線條數)
ValidateCode code = new ValidateCode(87, 33, 4, 23);
// 將驗證碼保存到 session 中,用于驗證
request.getSession().setAttribute("code", code.getCode());
// 響應返回驗證碼圖片 base64 編碼后的數據給瀏覽器
response.getWriter().write(ImageUtil.encodeImg2Base64(code.getBuffImg(), "png"));
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
this.doGet(request, response);
}
}說明:
這里使用了 Servlet3.0 的新特性-用注解配置 url-pattern(用起來挺爽的),也就是說簡單的項目不再需要 web.xml 了,但是 Tomcat 需要 7.0+。
其次生成驗證碼我用了一個小工具:ValidateCode.jar。工具十分簡單,不合心意完全可以自己寫。但也就是因為功能太少,所以我又寫了一個 ImageUtil。我也有打算自己開源一個驗證碼工具出來。
ImageUtil.java
package com.leo.util;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import sun.misc.BASE64Encoder;
public class ImageUtil {
/**
* 將圖片二進制數據進行 base64 編碼
* @param bufImg
* @return base64 編碼后的字符串
*/
public static String encodeImg2Base64(BufferedImage bufImg, String formatName) {
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
ImageIO.write(bufImg, formatName, outputStream);
} catch (IOException e) {
throw new RuntimeException("Base64 編碼失??!"+e.getMessage());
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(outputStream.toByteArray());
}
private ImageUtil() {} // 工具類私有化構造方法是常見的做法
}說明:
為什么要把圖片二進制數據進行 Base64編碼 呢?因為<img/>標簽雖然可以直接設置 src 屬性值為${pageContext.request.contextPath}/captcha/code請求相應的 Servlet 來得到二進制數據直接顯示,但在 AJAX 異步請求中響應返回的是 xhr.responseText 。當把數據直接給 img 標簽的 src 屬性時,用 Chrome-tool 查看只會是一堆二進制當作文本解析的亂碼字符,所以才要多這一步。
或許我作為萌新不知道一些其它的方便技巧。但若不想使用異步,那直接 img src 設置為請求地址將是最簡單的選擇,更換驗證碼無非是監聽事件 img src 重新設置為該地址(再來一次請求)。
詳細的資料:JS在瀏覽器中解析Base64編碼圖像
Base64圖片編碼解析及瀏覽器的兼容性處理
后臺驗證驗證碼:CheckServlet.jave
package com.leo.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/check")
public class CheckServlet extends HttpServlet {
private static final long serialVersionUID = -6588625852621588221L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String encoding = "UTF-8";
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
/* 驗證碼驗證 */
String inputCode = request.getParameter("code");
// 獲得 session 中的正確驗證碼
String realCode = (String) request.getSession().getAttribute("code");
System.out.println("input: "+inputCode+"\nreal: "+realCode); // 用于 Debug
if(!(inputCode!=null && realCode!=null &&
inputCode.equalsIgnoreCase(realCode))) {
// 若驗證碼不正確:回到頁面并提示錯誤
request.setAttribute("msg", "驗證碼錯誤!請重新輸入");
request.getRequestDispatcher("/demo1.jsp").forward(request, response);
return;
}
// 驗證碼正確,響應一句話表示 OK
response.getWriter().write("驗證成功!");
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}
}說明:
doGet() 方法一開始是對中文亂碼進行處理,編碼統一設為 UTF-8。在實際項目中,編碼問題通常交給一個 Filter 完成,達到一勞永逸的效果。
效果
警告!警告??!顏控請速速撤離?。?!

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。