註冊登入(設計圖片驗證碼)
阿新 • • 發佈:2018-11-09
圖片驗證碼的實現 (註冊、下單、支付均有涉及)
1. 目的:
1) 驗證操作者是否是人,不是機器。
2) 防止表單重複提交。每次提交要判斷驗證碼的正確與否
生成驗證碼的要點:
1) 使用java程式碼生成圖片物件
2) 使用Random生成隨機字串
3) 將圖片物件用
ImageIO.write(圖片物件, “jpeg|png”, 響應位元組輸出流)
返回給客戶端瀏覽器
驗證驗證碼:
要點:
1) 將驗證碼文字存入session作用域
2) 表單提交時,對比session中的驗證碼和表單中的驗證碼,用來判斷驗證碼輸入是否正確
2.程式碼實現:
第一步:建立圖片
public class CaptchaUtil { public static String[] array = {"a", "b", "c", "d", "e", "f", "g"}; public static String random() { Random random = new Random(); StringBuffer sb = new StringBuffer(3); //如果超出3,系統會自動擴充,一般情況下,將隨機數數字設定在範圍內,例如3,4,5,6 以new StringBuffer(3)為標準最佳 for (int i = 0; i < 3; i++) { int i1 = random.nextInt(array.length); sb.append(array[i1]); } return sb.toString(); } public static void outputImage(String str, OutputStream os) { //建立圖片 BufferedImage image = new BufferedImage(100, 80, BufferedImage.TYPE_INT_BGR); //物件獲得畫布 Graphics g = image.getGraphics(); //作畫,背景色 g.setColor(Color.WHITE); g.fillRect(0, 0, 100, 80); //前景色 g.setColor(Color.BLUE); //設定字型 g.setFont(new Font("宋體", Font.PLAIN, 36)); //寫字 g.drawString(str, 0, 40); //輸出結果 try { ImageIO.write(image, "png", os); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { String str = random(); outputImage(str, new FileOutputStream("e:\\2.png")); } }
第二步:將隨機產生的字串存入session中,並且讓圖片作為響應
@WebServlet(urlPatterns = "/captcha.png") public class CatcherServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("image/png"); String s = CaptchaUtil.random(); //將隨機產生的字串存入session作用域,便於圖片驗證碼驗證時對比 req.getSession().setAttribute("captcha",s); //圖片作為響應 resp.getoutputStream() CaptchaUtil.outputImage(s,resp.getOutputStream()); } }
第三步:表單提交部分
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/register" method="post">
<table>
<tr>
<td>使用者名稱</td>
<td><input type="text" name="username" id="username"></td>
</tr>
<tr>
<td>密碼</td>
<td><input type="password" name="password" id="password"></td>
</tr>
<tr>
<%--圖片的地址就是獲取圖片的servlet的地址--%>
<td><img src="/captcha.png" onclick="changeImg(this)"></td>
<td><input type="text" name="captcha"> ${requestScope.error} </td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="註冊"> </td>
</tr>
</table>
</form>
<script>
// 點選事件是為了每次點選圖片驗證碼,驗證碼都會變化,由於考慮到個別瀏覽器的快取,圖片不會變化,所以我們+new Date().getTime()
function changeImg(img)
{
img.src="/captcha.png?t="+new Date().getTime();
}
</script>
</body>
</html>
第四步: 提交後驗證輸入的驗證碼是否正確,如果不正確,重新調回提交介面(這裡旨在校驗驗證碼功能,沒有獲取判斷使用者名稱等提交資訊,驗證成功後只在控制檯輸出“驗證成功”字樣,僅僅為檢視效果,實際情況下,驗證成功過後應跳轉到其他介面)
@WebServlet(urlPatterns = "/register")
public class RegisterServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String captcha = req.getParameter("captcha");
Object captcha1 = req.getSession().getAttribute("captcha");
if(captcha !=null && captcha.equals(captcha1)){
//判斷得出驗證碼和所填寫的驗證碼一致,表示填寫正確
req.getSession().removeAttribute("captcha1");//銷燬session值
System.out.println("驗證成功");
}
else {
req.setAttribute("error","驗證碼不正確");
req.getRequestDispatcher("yanzheng.jsp").forward(req,resp);
}
}
}