使用Servlet生成验证码图片

使用Servlet生成验证码效果

这里写图片描述

实现原理
  1. 使用java.awt.image.BufferedImage创建图片
  2. 在图片上绘制验证信息(我这里写一个数学表达式)
  3. 在图片上添加干扰线
  4. 用Servlet控制响应头使浏览器以图片的方式打开
  5. 并设置浏览器不缓存当前文档
  6. 用ImageIO.write()方法输出
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;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * Created by kay on 2016/10/21.
 */
@WebServlet(name = "ResponseImage3",urlPatterns = {"/responseimage3"})
public class ResponseImage3 extends HttpServlet {
    public static final int WIDTH=120;
    public static final int HEIGHT=30;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_BGR);
        Graphics g=image.getGraphics();
        //背景
        g.setColor(Color.white);
        g.fillRect(0,0,WIDTH,HEIGHT);

        //边框
        g.setColor(Color.BLACK);
        g.drawRect(1,1,WIDTH-2,HEIGHT-2);
        drawRandomLine(g);
        //生成随机数
        Random random=new Random();
        int a=random.nextInt(100);
        int b=random.nextInt(100);
        int sum=a+b;
        Graphics2D g1=(Graphics2D)g;
        g1.setColor(Color.BLACK);
        g1.setFont(new Font(null,Font.ITALIC,20));
        g1.drawString(a+"+"+b+"= ?",20,HEIGHT-5);
         //将验证结果保存到Session中
        request.getSession().setAttribute("checkcode1",sum+"");
        //设置浏览器以图片格式输出
        response.setContentType("image/jpeg");
        //设置响应头控制浏览器不要缓存
        response.setDateHeader("expries", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        //将图片写给浏览器
        ImageIO.write(image, "jpg", response.getOutputStream());
    }

    //画几条随机的干扰线
    private void drawRandomLine(Graphics g) {
        // 设置颜色
        g.setColor(Color.GREEN);
        // 设置线条个数并画线
        for (int i = 0; i < 5; i++) {
            int x1 = new Random().nextInt(WIDTH);
            int y1 = new Random().nextInt(HEIGHT);
            int x2 = new Random().nextInt(WIDTH);
            int y2 = new Random().nextInt(HEIGHT);
            g.drawLine(x1, y1, x2, y2);
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

前台写一个Form表单用来验证

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2016/10/21
  Time: 17:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page import="java.util.*" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript">
        //刷新验证码
        function changeImg(){            document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/responseimage3?"+Math.random();
        }
    </script>
</head>
<body>
<form action="${pageContext.request.contextPath}/checkimage" method="post">
    验证码:<input type="text" name="validateCode"/>
    <img alt="验证码看不清,换一张" src="${pageContext.request.contextPath}/responseimage3" id="validateCodeImg" onclick="changeImg()">
    <a href="javascript:void(0)" onclick="changeImg()">看不清,换一张</a>
    <br/>
    <input type="submit" value="提交">
</form>
</body>
</html>
注意:
function changeImg(){            document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/responseimage3?"+Math.random();
}

调用生成验证码图片的Servlet的时候传入一个随机的参数(Math.random),是为了与上一次的请求相区别,服务器对2次相同的请求会返回同一个结果,为了刷新图片那需要使用不同的请求。

提交验证码之后传到CheckImage这个servlet来检查是否输入正确

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by kay on 2016/10/21.
 */
@WebServlet(name = "CheckImage",urlPatterns = {"/checkimage"})
public class CheckImage extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String clientCheckcode = request.getParameter("validateCode");//接收客户端浏览器提交上来的验证码
        String serverCheckcode = (String) request.getSession().getAttribute("checkcode");//从服务器端的session中取出验证码

        String checkcode1=(String) request.getSession().getAttribute("checkcode1");

        if (clientCheckcode.equals(checkcode1)) {//将客户端验证码和服务器端验证比较,如果相等,则表示验证通过
            System.out.println("验证码验证通过!");
            response.sendRedirect(request.getContextPath()+"/success.jsp");
        }else {
            System.out.println("验证码验证失败!");
            response.sendRedirect(request.getContextPath()+"/failure.jsp");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

到此这个小功能就完成了。点击图片更换验证码,输入结果进行验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带着天使反上帝 - Kaybee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值