用jsp实现异步验证码校验功能
众所周知,网站上的验证码的作用是保护网站安全,一般网站都要通过验证码来防止机器大规模注册,机器暴力破解数据密码等危害。
1. 示例
2. img.jsp生成验证码图像的jsp文件
a. 生成颜色随机值和四位数的验证码值
//随机产生颜色值
public Color getColor(){
Random random = new Random();
int rgb1 = random.nextInt(256); //[0-256)
int rgb2 = random.nextInt(256);
int rgb3 = random.nextInt(256);
return new Color(rgb1,rgb2,rgb3);//RGB值 0-255
}
//产生四位数验证码值
public String getNum(){
int random = (int)(Math.random() * 9000 + 1000);
return String.valueOf(random);
}
b. 设置验证码头信息
//禁止缓存,防止验证码过期
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-control","no-cache");
response.setHeader("Expires","0");//过期时间
c. 获取画笔开始绘制
//绘制验证码
BufferedImage image = new BufferedImage(80,30,BufferedImage.TYPE_INT_RGB);//宽、高、类型
//画笔
Graphics graphics = image.getGraphics();
graphics.fillRect(0,0,80,30);//0,0填充到80,30
//绘制验证码干扰线条,随机
for (int i = 0; i < 60; i++) {
Random random = new Random();
int xBegin = random.nextInt(80);
int yBegin = random.nextInt(30);//线条起始位置
int xEnd = random.nextInt(xBegin + 10);
int yEnd = random.nextInt(yBegin + 10);//线条终止位置
graphics.setColor(getColor());//画笔颜色随机
//绘制线条
graphics.drawLine(xBegin,yBegin,xEnd,yEnd);
}
//即将绘制验证码
graphics.setFont(new Font("seif",Font.BOLD,20));//设置字体参数
graphics.setColor(Color.BLACK);//设置验证码颜色
String checkCode = getNum();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < checkCode.length(); i++) {
sb.append(checkCode.charAt(i) + " ");//拿到4位数字的每位数字
}
//绘制验证码
graphics.drawString(sb.toString(),15,20);
//将真实验证码保存在session中发送给servlet,用来比较正确与否
session.setAttribute("CHECKCODE",checkCode);
//真实产生图片
ImageIO.write(image,"jpeg",response.getOutputStream());
//关闭
out.clear();
out = pageContext.pushBody();
3. index.jsp展示给用户、发送请求给servlet的jsp文件
a. body体
<body>
验证码:
<input type="text" name="checkcode" id="checkcodeId" size="4">
<!--验证码-->
<a href="javascript:reloadCheckImg();"><img src="img.jsp"></a>
<span id="tip"></span>
</body>
b. js和ajax部分
script type="text/javascript">
//点击图片完成图片刷新
function reloadCheckImg(){
$("img").attr("src","img.jsp?t=" + (new Date().getTime()));//不加?后面参数浏览器会保存当前缓存,图片无法刷新
}
$(document).ready(function (){
//失去焦点blur、聚焦focus
$("#checkcodeId").blur(function (){
//获取验证码的值
var checkcode = $("#checkcodeId").val();
//校验、使用ajax完成异步校验
$.post(
"CheckCodeServlet",//服务端地址
"checkcode="+checkcode,
function (result){
//服务端返回图片地址
var $result = $("<img src='"+result+"' height='15px' width='15px'>")
$("#tip").html($result);
}
);
});
});
</script>
4. servlet进行校验
由于我们发送的请求是post方式,因此我们只要实现servlet中的post方法即可。
拿到img.jsp发送来的真实验证码与index.jsp用户输入的验证码对比,相同则返回right.jpg;不同则返回wrong.jsp。
public class CheckCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String resImg = "imgs/wrong.jpg";
//获取用户输入的验证码
String checkcodeClient = request.getParameter("checkcode");
//真实的验证码值
String checkcodeServer = (String) request.getSession().getAttribute("CHECKCODE");
if (checkcodeServer.equals(checkcodeClient)){
resImg = "imgs/right.jpg";
}
System.out.println(resImg);
System.out.println(checkcodeClient);
System.out.println(checkcodeServer);
response.setContentType("text/html; charset=UTF-8");
//输出流
PrintWriter writer = response.getWriter();
writer.write(resImg);
writer.close();
}
5. 全部代码
a. img.jsp
<%@ page import="java.awt.*" %>
<%@ page import="java.util.Random" %>
<%@ page import="java.awt.image.BufferedImage" %>
<%@ page import="javax.imageio.ImageIO" %>
<%@ page contentType="image/jpeg;charset=UTF-8" language="java" %>
<%!
//随机产生颜色值
public Color getColor(){
Random random = new Random();
int rgb1 = random.nextInt(256); //[0-256)
int rgb2 = random.nextInt(256);
int rgb3 = random.nextInt(256);
return new Color(rgb1,rgb2,rgb3);//RGB值 0-255
}
//产生四位数验证码值
public String getNum(){
int random = (int)(Math.random() * 9000 + 1000);
return String.valueOf(random);
}
%>
<%
//禁止缓存,防止验证码过期
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-control","no-cache");
response.setHeader("Expires","0");//过期时间
//绘制验证码
BufferedImage image = new BufferedImage(80,30,BufferedImage.TYPE_INT_RGB);//宽、高、类型
//画笔
Graphics graphics = image.getGraphics();
graphics.fillRect(0,0,80,30);//0,0填充到80,30
//绘制验证码干扰线条,随机
for (int i = 0; i < 60; i++) {
Random random = new Random();
int xBegin = random.nextInt(80);
int yBegin = random.nextInt(30);//线条起始位置
int xEnd = random.nextInt(xBegin + 10);
int yEnd = random.nextInt(yBegin + 10);//线条终止位置
graphics.setColor(getColor());//画笔颜色随机
//绘制线条
graphics.drawLine(xBegin,yBegin,xEnd,yEnd);
}
//即将绘制验证码
graphics.setFont(new Font("seif",Font.BOLD,20));//设置字体参数
graphics.setColor(Color.BLACK);//设置验证码颜色
String checkCode = getNum();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < checkCode.length(); i++) {
sb.append(checkCode.charAt(i) + " ");//拿到4位数字的每位数字
}
//绘制验证码
graphics.drawString(sb.toString(),15,20);
//将真实验证码保存在session中,用来比较正确与否
session.setAttribute("CHECKCODE",checkCode);
//真实产生图片
ImageIO.write(image,"jpeg",response.getOutputStream());
//关闭
out.clear();
out = pageContext.pushBody();
%>
b. index.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery-3.3.1.min.js">
</script>
<script type="text/javascript">
//点击图片完成图片刷新
function reloadCheckImg(){
$("img").attr("src","img.jsp?t=" + (new Date().getTime()));//不加?后面参数浏览器会保存当前缓存,无法刷新
}
$(document).ready(function (){
//失去焦点blur、聚焦focus
$("#checkcodeId").blur(function (){
//获取验证码的值
var checkcode = $("#checkcodeId").val();
//校验
$.post(
"CheckCodeServlet",//服务端地址
"checkcode="+checkcode,
function (result){
//服务端返回图片地址
var $result = $("<img src='"+result+"' height='15px' width='15px'>")
$("#tip").html($result);
}
);
});
});
</script>
<title>验证码</title>
</head>
<body>
验证码:
<input type="text" name="checkcode" id="checkcodeId" size="4">
<!--验证码-->
<a href="javascript:reloadCheckImg();"><img src="img.jsp"></a>
<span id="tip"></span>
</body>
</html>
c. CheckCodeServlet.java
package com.yhr.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "CheckCodeServlet", value = "/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String resImg = "imgs/wrong.jpg";
//获取用户输入的验证码
String checkcodeClient = request.getParameter("checkcode");
//真实的验证码值
String checkcodeServer = (String) request.getSession().getAttribute("CHECKCODE");
if (checkcodeServer.equals(checkcodeClient)){
resImg = "imgs/right.jpg";
}
System.out.println(resImg);
System.out.println(checkcodeClient);
System.out.println(checkcodeServer);
response.setContentType("text/html; charset=UTF-8");
//输出流
PrintWriter writer = response.getWriter();
writer.write(resImg);
writer.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}