使用Servlet生成验证码

本文演示如何在Servlet中生成随机验证码。

1 编写index.jsp

index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>一点教程网-使用Servlet生成验证码</title>
</head>
<body>
<h1>使用Servlet生成验证码</h1>
<a href="VaidateCode">生成验证码</a>
</body>
</html>

2 编写ImageUtil

ImageUtil用于生成随机验证码:

import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 一点教程网 - http://www.yiidian.com
 */
public class ImageUtil {

    private ImageUtil() {};
    private static final Random r = new Random();
    private static final int width = 148;
    private static final int height = 26;


    private static final char[] c= {
            'a','b','c','d','e','f','g','h','i','j',
            'k','l','m','n','o','p','q','r','s','t',
            'u','v','w','x','y','z',
            '0','1','2','3','4','5','6','7','8','9'
    };

    public static final BufferedImage createImage(HttpSession session, int length) {

        //根据宽高创建一张缓冲区图像, 图像使用的是正整数的RGB格式
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //从图像中获取画笔
        Graphics g = bi.getGraphics();
        //设置画笔颜色
        g.setColor(new Color(175,215,151));
        //使用画笔填充矩形,背景色
        setBackGround(g);
        //设置干扰线
        drowRandomLine((Graphics2D)g);
        StringBuilder sb = new StringBuilder();

        for(int i=0; i < length; i++) {
            int index = r.nextInt(c.length);
            sb.append(c[index]);
            //设置字体
            g.setFont(new Font("微软雅黑",Font.PLAIN,r.nextInt(5)+15));
            g.setColor(new Color(r.nextInt(200),r.nextInt(200),r.nextInt(200)));
            g.drawString(Character.toString(c[index]), (i+1)*20, 18);
        }
        //将验证码存入到session中
        session.setAttribute("sb", sb.toString());
        g.dispose();
        return bi;
    }


    /** 设置背景颜色 */
    private static void setBackGround(Graphics g) {
        //设置画笔颜色
        g.setColor(Color.white);
        //填充区域
        g.fillRect(0, 0, width, height);
    }

    /** 干扰线 */
    private static void drowRandomLine(Graphics2D g) {
        g.setStroke(new BasicStroke(0.3f));
        //设置线条数目, 线条颜色
        for(int i=0; i<3;i++) {
            //每次颜色随机
            g.setColor(new Color(r.nextInt(10),r.nextInt(10),r.nextInt(10)));
            int x1 = r.nextInt(width);
            int y1 = r.nextInt(height);
            int x2 = r.nextInt(width);
            int y2 = r.nextInt(height);
            g.drawLine(x1, y1, x2, y2);
        }
    }

}

3 编写VaidateCodeServlet

ValidateCodeServlet用于调用ImageUtil展示随机验证码到浏览器:


import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * 一点教程网 - http://www.yiidian.com
 */
public class VaidateCodeServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //创建图像
        BufferedImage bi = ImageUtil.createImage(request.getSession(), 5);
        //以png格式   输出响应流到界面
        ImageIO.write(bi, "png", response.getOutputStream());

        /** 设置浏览器不缓存图片*/
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("expires", -1);
    }
}

4 配置web.xml

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>VaidateCodeServlet</servlet-name>
        <servlet-class>VaidateCodeServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>VaidateCodeServlet</servlet-name>
        <url-pattern>/VaidateCode</url-pattern>
    </servlet-mapping>

</web-app>

5 运行测试

一点教程,一个分享编程知识的公众号。跟着站长一起学习和进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

在公交、在地铁、在厕所都可以阅读,随时随地涨姿势。

文章不涉及代码,不烧脑细胞,人人都可以学习。

当你决定关注「一点教程」,你已然超越了90%的程序员!

一点教程二维码