图片验证码的实现 (注册、下单、支付均有涉及)
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);
}
}
}