1. 开发环境
|-- tomcat7
|-- eclipse
|-- jdk1.7
2. 项目结构
|-- demo
|-- src
|-- asia.hchx.filter
|-- CharacterFilter
|-- LoginFilter
|-- asia.hchx.servlet
|-- LoginServlet
|-- VerifyImage
|-- WebContent
|-- index.jsp
|-- login.jsp
3. 测试步骤
|-- 创建web项目
|-- 配置开发图形验证码Servlet
package asia.phome.servlet;
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;
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("/verifyCode.do")
public class VerifyImage extends HttpServlet {
// 产生随即的字体
private Font getFont() {
Random random = new Random();
Font font[] = new Font[5];
font[0] = new Font("Ravie", Font.PLAIN, 24);
font[1] = new Font("Antique Olive Compact", Font.PLAIN, 24);
font[2] = new Font("Forte", Font.PLAIN, 24);
font[3] = new Font("Wide Latin", Font.PLAIN, 24);
font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, 24);
return font[random.nextInt(5)];
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置响应头 Content-type类型
resp.setContentType("image/jpeg");
// 以下三句是用于设置页面不缓存
resp.setHeader("Pragma", "No-cache");
resp.setHeader("Cache-Control", "No-cache");
resp.setDateHeader("Expires", 0);
OutputStream os = resp.getOutputStream();
int width = 83, height = 30;
// 建立指定宽、高和BufferedImage对象
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics(); // 该画笔画在image上
Color c = g.getColor(); // 保存当前画笔的颜色,用完画笔后要回复现场
g.fillRect(0, 0, width, height);
char[] ch = "abcdefghigklmnopqrstuvwxyz"
.concat("ABCDEFGHIJKLMNOPQRSTUV")
.concat("WXYZ0123456789").toCharArray(); // 随即产生的字符串
// 不包括 i
// l(小写L)
// o(小写O)
// 1(数字1)0(数字0)
int length = ch.length; // 随即字符串的长度
String sRand = ""; // 保存随即产生的字符串
Random random = new Random();
for (int i = 0; i < 4; i++) {
// 设置字体
g.setFont(getFont());
// 随即生成0-9的数字
String rand = new Character(ch[random.nextInt(length)]).toString();
sRand += rand;
// 设置随机颜色
g.setColor(new Color(random.nextInt(255), random.nextInt(255),
random.nextInt(255)));
g.drawString(rand, 20 * i + 6, 25);
}
// 产生随即干扰点
for (int i = 0; i < 40; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
g.drawOval(x1, y1, 2, 2);
}
g.setColor(c); // 将画笔的颜色再设置回去
g.dispose();
// 将验证码记录到session
req.getSession().setAttribute("safecode", sRand);
// 输出图像到页面
ImageIO.write(image, "JPEG", os);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
|-- 登录页面配置图形验证码login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath }/login.do">
username:<input type="text" name="username"/><br />
password:<input type="text" name="password"/><br />
<!-- img中的src属性中,配置VerifyImage的请求 -->
verify code:<img src="${pageContext.request.contextPath }/verifyCode.do"/>
<input type="text" name="verifyCode"/>
<br />
<input type="checkbox" value="1" name="rememberMe"/>记住密码
<br />
<input type="submit" value="登陆"/>
</form>
</body>
</html>
|-- 登录的Servlet配置——LoginServlet
package asia.phome.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
@WebServlet("/login.do")
public class LoginServlet extends HttpServlet{
Logger log = Logger.getLogger(LoginServlet.class);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
log.debug("开始执行doGet方法");
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
log.debug("开始执行doPost方法");
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
log.debug("开始接收参数");
String username = req.getParameter("username");
String password = req.getParameter("password");
String safeCode = req.getParameter("verifyCode");
log.debug("接收到参数:username ="
+ username
+ ";password=" + password
+ ";safecode=" + safeCode);
// 获取验证码
String sc = (String) req.getSession().getAttribute("safecode");
log.warn("服务器中的验证码:" + sc);
if (!sc.equalsIgnoreCase(safeCode)) {
log.warn("验证码输入有误!");
resp.sendRedirect("login.jsp");
return;
}
String isRe = req.getParameter("rememberMe");
log.debug("是否记住密码:" + isRe);
if ("1".equals(isRe)) {
/*
* 记住密码
* 在客户端的Cookie中,写入一个字符串标识
*/
// 创建cookie
log.debug("创建Cookie");
Cookie cookie = new Cookie("rememberMe", username);
// 将cookie绑定到响应中
log.debug("绑定Cookie到响应中");
resp.addCookie(cookie);
}
if ("admin".equals(username)
&& "admin".equals(password)) {
log.debug("登录成功,跳转到Index.jsp页面");
req.getSession().setAttribute("loginuser", username);
resp.sendRedirect("index.jsp");
} else {
log.debug("登录失败,跳转到error.jsp页面");
resp.sendRedirect("error.jsp");
}
}
}
|-- 测试
运行项目,页面上出现如下图形验证码