jsp實現驗證碼

NO IMAGE

1、驗證碼主要是為了防止前段噁心提交資料使用的。

利用servlet輸出一張圖片:

package com.xingxue.filter;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class CodeServlet
*/
public class CodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CodeServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//圖片物件
BufferedImage bfi = new BufferedImage(80,40,BufferedImage.TYPE_INT_RGB);
Graphics g = bfi.getGraphics();
g.fillRect(0, 0, 80, 40);
//62 * 62 *62 *62* 62* 62 *62
//驗證碼字元範圍
char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
Random r = new Random(); 
int index;  
StringBuffer sb = new StringBuffer(); //儲存字串
for(int i=0; i<4; i  ){
index = r.nextInt(ch.length);
g.setColor(new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255)));
Font font = new Font("宋體", 30, 20);
g.setFont(font);
g.drawString(ch[index] "", (i*20) 2, 23);
sb.append(ch[index]);
}
// 新增噪點
int area = (int) (0.02 * 80 * 40);
for(int i=0; i<area;   i){
int x = (int)(Math.random() * 80);
int y = (int)(Math.random() * 40);
bfi.setRGB(x, y, (int)(Math.random() * 255));
}
//設定驗證碼中的干擾線
for (int i = 0; i < 5; i  ) {  
//隨機獲取干擾線的起點和終點
int xstart = (int)(Math.random() * 80);
int ystart = (int)(Math.random() * 40);
int xend = (int)(Math.random() * 80);
int yend = (int)(Math.random() * 40);
g.setColor(interLine(1, 255));
g.drawLine(xstart, ystart, xend, yend);
}
HttpSession session = request.getSession();  //儲存到session
session.setAttribute("code", sb.toString());
ImageIO.write(bfi, "JPG", response.getOutputStream());  //寫到輸出流
}
private static Color interLine(int Low, int High){
if(Low > 255)
Low = 255;
if(High > 255)
High = 255;
if(Low < 0)
Low = 0;
if(High < 0)
High = 0;
int interval = High - Low;
int r = Low   (int)(Math.random() * interval);
int g = Low   (int)(Math.random() * interval);
int b = Low   (int)(Math.random() * interval);
return new Color(r, g, b);
}
}

2、頁面表單加入

利用img 的src 指向該servlet,及可以實現驗證碼顯示

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath()   "/";
%>
<!DOCTYPE HTML>
<html>
<head>
<title>Sign In</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="keywords" content="" />
<script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
<!-- Bootstrap Core CSS -->
<link href="<%=path %>css/bootstrap.min.css" rel='stylesheet' type='text/css' />
<!-- Custom CSS -->
<link href="<%=path %>css/style.css" rel='stylesheet' type='text/css' />
<link rel="stylesheet" href="<%=path %>css/morris.css" type="text/css"/>
<!-- Graph CSS -->
<link href="<%=path %>css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="<%=path %>css/jquery-ui.css"> 
<!-- jQuery -->
<script src="<%=path %>js/jquery-2.1.4.min.js"></script>
<!-- //jQuery
<link href='http://fonts.googleapis.com/css?family=Roboto:700,500,300,100italic,100,400' rel='stylesheet' type='text/css'/>
<link href='http://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
-->
<!-- lined-icons -->
<link rel="stylesheet" href="<%=path %>css/icon-font.min.css" type='text/css' />
<!-- //lined-icons -->
<script type="text/javascript">
function changeYZM() {
var yzm = document.getElementById("loginYZM");
yzm.src= "<%=path%>/CodeServlet?num=" Math.random();
}
</script>
</head> 
<body>
<div class="main-wthree">
<div class="container">
<div class="sin-w3-agile">
<h2>後 臺 系 統</h2>
<h2 style="font-size:16px; color:red"> ${msg }</h2>
<form action="<%=path %>admin/adminLogin.action" method="post">
<div class="username">
<span class="username">賬號:</span>
<input type="text" name="requestParam.account" class="name" placeholder="賬號" required="">
<div class="clearfix"></div>
</div>
<div class="password-agileits">
<span class="username">密碼:</span>
<input type="password" name="requestParam.pwd" class="password" placeholder="密碼" required="">
<div class="clearfix"></div>
</div>
<div class="password-agileits">
<span class="username">驗證碼:</span>
<input type="test" name="requestParam.yzm" style="width:200px;" class="password" placeholder="驗證碼" required="">
&nbsp;<img id="loginYZM" src="<%=path%>/CodeServlet" onclick="changeYZM()">
<div class="clearfix"></div>
</div>
<div class="rem-for-agile">
<input type="checkbox" name="remember" class="remember">記住密碼<br>
<a href="#">忘記密碼?</a><br>
</div>
<div class="login-w3">
<input type="submit" class="login" value="登     陸">
</div>
<div class="clearfix"></div>
</form>
<div class="back">
</div>
<div class="footer">
<p>&copy; 2016 Pooled . All Rights Reserved | Design by <a href="http://w3layouts.com">W3layouts</a></p>
</div>
</div>
</div>
</div>
</body>
</html>

3、在登陸的action裡面通過session獲取判斷眼:

HttpSession session = ServletActionContext.getRequest().getSession();
String code = (String) session.getAttribute("code");
if(code != null && code.equals("" requestParam.get("yzm"))) {
responseParam = this.service.adminLogin(requestParam);
if(responseParam

驗證碼的本質就是利用servlet輸出一張圖片,然後隨機往圖片裡面寫入不同的數字,達到攔截請求的效果,當然這種方式使用者體驗不要,現在都流行用圖片,原因是防偽能力更強,使用者體驗更好