用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);
    }
}

Guess you like

Origin blog.csdn.net/qq_43960954/article/details/121196094