---使用HttpSession實現驗證碼功能
阿新 • • 發佈:2019-02-11
原理
原理和使用session來防止表單重複提交一樣,只是在提交的時候,將表單中隱藏域替換成接受使用者輸入的內容。
實現
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>
<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>
<body>
This is my JSP page.
<br>
<form action="<%=request.getContextPath()%>/checkCodeServlet"
method="post">
Username:<input type="text" name="username" /><br> <br> <br>CheckCode:
<input type="text" name="CHECK_CODE_PARAM_CODE" />
<!-- 驗證碼Sevlet -->
<img alt="" src="<%=request.getContextPath()%>/validateColorServlet">
<font color="RED"> <%=session.getAttribute("message") == null ? "" : session
.getAttribute("message")%> <%
session.removeAttribute("message");
%> </font><input type="submit" value="submit" />
</form>
</body>
</html>
ValidateColorServlet.java
package com.aaa.checkcode;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 驗證碼Servlet,返回驗證碼圖片,並且把驗證碼的值放入session中
*
* @author tuxianchao
*
*/
public class ValidateColorServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final String CHECK_CODE_KEY = "CHECK_CODE_KEY";
// 驗證碼圖片的寬度, 高度, 驗證碼的個數
private int width = 152;
private int height = 40;
private int codeCount = 4;
// 驗證碼字型的高度
private int fontHeight = 4;
// 驗證碼中的單個字元基線. 即:驗證碼中的單個字元位於驗證碼圖形左上角的 (codeX, codeY) 位置處
private int codeX = 0;
private int codeY = 0;
// 驗證碼由哪些字元組成
char[] codeSequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz23456789"
.toCharArray();
// 初始化驗證碼圖形屬性
public void init() {
fontHeight = height - 2;
codeX = width / (codeCount + 2);
codeY = height - 4;
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 定義一個型別為 BufferedImage.TYPE_INT_BGR 型別的影象快取
BufferedImage buffImg = null;
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
// 在 buffImg 中建立一個 Graphics2D 影象
Graphics2D graphics = null;
graphics = buffImg.createGraphics();
// 設定一個顏色, 使 Graphics2D 物件的後續圖形使用這個顏色
graphics.setColor(Color.WHITE);
// 填充一個指定的矩形: x - 要填充矩形的 x 座標; y - 要填充矩形的 y 座標; width - 要填充矩形的寬度; height
// - 要填充矩形的高度
graphics.fillRect(0, 0, width, height);
// 建立一個 Font 物件: name - 字型名稱; style - Font 的樣式常量; size - Font 的點大小
Font font = null;
font = new Font("", Font.BOLD, fontHeight);
// 使 Graphics2D 物件的後續圖形使用此字型
graphics.setFont(font);
graphics.setColor(Color.BLACK);
// 繪製指定矩形的邊框, 繪製出的矩形將比構件寬一個也高一個畫素
graphics.drawRect(0, 0, width - 1, height - 1);
// 隨機產生 100 條幹擾線,
Random random = null;
random = new Random();
graphics.setColor(Color.GREEN);
for (int i = 0; i < 100; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(20);
int y1 = random.nextInt(20);
graphics.drawLine(x, y, x + x1, y + y1);
}
// 建立 randomCode 物件, 用於儲存隨機產生的驗證碼, 以便使用者登入後進行驗證
StringBuffer randomCode;
randomCode = new StringBuffer();
for (int i = 0; i < codeCount; i++) {
// 得到隨機產生的驗證碼數字
String strRand = null;
strRand = String.valueOf(codeSequence[random.nextInt(36)]);
// 把正在產生的隨機字元放入到 StringBuffer 中
randomCode.append(strRand);
// 用隨機產生的顏色將驗證碼繪製到影象中
graphics.setColor(Color.BLUE);
graphics.drawString(strRand, (i + 1) * codeX, codeY);
}
// 再把存放有所有隨機字元的 StringBuffer 對應的字串放入到 HttpSession 中
request.getSession()
.setAttribute(CHECK_CODE_KEY, randomCode.toString());
System.out.println("產生的驗證碼---" + randomCode.toString());
// 禁止影象快取
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 將影象輸出到輸出流中
ServletOutputStream sos = null;
sos = response.getOutputStream();
ImageIO.write(buffImg, "jpeg", sos);
sos.close();
}
}
CheckCodeServlet.java
package com.aaa.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CheckCodeServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 獲取請求引數:CHECK_CODE_PARAM_NAME
String checkCodeFromForm = request
.getParameter("CHECK_CODE_PARAM_CODE");
// 獲取session的CHECK_CODE_KEY
String checkCodeFromSession = (String) request.getSession()
.getAttribute("CHECK_CODE_KEY");
System.out.println("使用者提交的---" + checkCodeFromForm);
System.out.println("session中的---" + checkCodeFromSession);
// 驗證
if (checkCodeFromForm != null
& checkCodeFromForm.equals(checkCodeFromSession)) {
// 合法 ,處理請求
System.out.println("處理請求....");
} else {
// 不合法,返回頁面,提示驗證碼錯誤
request.getSession().setAttribute("message", "驗證碼錯誤");
response.sendRedirect(request.getContextPath()
+ "/checkCode/index.jsp");
}
}
}
總結
分析:在訪問index.jsp的時候,驗證碼圖片由一個servlet產生,同時將產生的驗證碼放入session中,在提交到servlet的時候,驗證提交過來的驗證碼和session中的驗證碼是否一致,如果一致正確響應請求,如果不一致,重定向到之前頁面,同時提示驗證碼錯誤。