Javaweb 响应——生成验证码

简介: Javaweb 响应——生成验证码

使用Servlet生成验证码


如何使用Servlet生成验证码


在Java中我们可以在Web项目中使用Servlet来生成验证码,流程是:前端请求验证码servlet对应的地址,后端servlet收到请求,生成一串字符作为验证码,存入到Session中,最后将验证码作为一张图片返回给前端。前端填写了验证码提交到服务器来验证。


我们看一个示例,你也可以根据这个示例在右侧编辑器中一步一步实现验证码的功能。


项目和servlet已经创建好了,我们首先在web.xml文件中注册servlet。


步骤


在servlet的doGet()方法中编写代码实现生成图片验证码:


分为如下步骤:


  1. 定义图像数据缓冲区(BufferedImage);


  1. 创建图片对象;


  1. 创建绘制工具(Graphics);


  1. 生成随机数,存入到session中;


  1. 使用Graphics绘制图形;


  1. 将验证码通过图像输出流(ImageIO)输出到客户端;


  1. 最后输入验证码地址即可访问单验证码。


代码如下:


protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 使用验证码的步骤
    // 定义图片的宽高
    int height = 20;
    int width = 60;
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    // 绘图工具
    Graphics graphics = image.getGraphics();
    // 绘制矩形
    graphics.setColor(getRandColor());
    // 绘制矩形背景 前两个参数 是 x y的坐标
    graphics.fillRect(0, 0, width, height);
    // 设置文字的颜色 为白色
    graphics.setColor(Color.WHITE);
    String yzm = "";
    // 生成四个随机数字并且画在图片上
    for (int i = 1; i <= 4; i++) {
        // 生成随机数字并且显示到页面上
        int number = new Random().nextInt(10);
        yzm += number;
        graphics.drawString(number + "", 10 * i, 10);
    }
    // 将验证码放入Httpsession中
    HttpSession session = req.getSession();
    session.setAttribute("sessionYzm", yzm);
    // 将验证码图片输出到客户端
    ImageIO.write(image, "jpg", resp.getOutputStream());
}
// 获取随机颜色
private Color getRandColor() {
    int red = new Random().nextInt(255);
    int green = new Random().nextInt(255);
    int blue = new Random().nextInt(255);
    return new Color(red, green, blue);
}


效果如下:



验证码案例:


案例1:


效果



html


html中,没点击一次img 标签(即验证码图片)就会请求一次servlet得到一个响应,重新绘制验证码图案。


<div class="verify">
  <input name="check" type="text" placeholder="请输入验证码" autocomplete="off">
  <span><img src="checkCode" alt="" onclick="changeCheckCode(this)"></span>
  <script type="text/javascript">
    //图片点击事件
    function changeCheckCode(img) {
      img.src="checkCode?"+new Date().getTime();
      // console.log  (new Date().getTime());
      // 时间戳
    }
  </script>
</div>


servlet


package cn.itcast.travel.web.servlet;
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;
/**
 * 验证码
 */
@WebServlet("/checkCode")
public class CheckCodeServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
    //服务器通知浏览器不要缓存
    response.setHeader("pragma","no-cache");
    response.setHeader("cache-control","no-cache");
    response.setHeader("expires","0");
    //在内存中创建一个长80,宽30的图片,默认黑色背景
    //参数一:长
    //参数二:宽
    //参数三:颜色
    int width = 80;
    int height = 30;
    BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    //获取画笔
    Graphics g = image.getGraphics();
    //设置画笔颜色为灰色
    g.setColor(Color.GRAY);
    //填充图片
    g.fillRect(0,0, width,height);
    //产生4个随机验证码,12Ey
    String checkCode = getCheckCode();
    //将验证码放入HttpSession中
    request.getSession().setAttribute("CHECKCODE_SERVER",checkCode);
    //设置画笔颜色为黄色
    g.setColor(Color.YELLOW);
    //设置字体的小大
    g.setFont(new Font("黑体",Font.BOLD,24));
    //向图片上写入验证码
    g.drawString(checkCode,15,25);
    //将内存中的图片输出到浏览器
    //参数一:图片对象
    //参数二:图片的格式,如PNG,JPG,GIF
    //参数三:图片输出到哪里去
    ImageIO.write(image,"PNG",response.getOutputStream());
  }
  /**
   * 产生4位随机字符串 
   */
  private String getCheckCode() {
    String base = "0123456789ABCDEFGabcdefg";
    int size = base.length();
    Random r = new Random();
    StringBuffer sb = new StringBuffer();
    for(int i=1;i<=4;i++){
      //产生0到size-1的随机值
      int index = r.nextInt(size);
      //在base字符串中获取下标为index的字符
      char c = base.charAt(index);
      //将c放入到StringBuffer中去
      sb.append(c);
    }
    return sb.toString();
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    this.doGet(request,response);
  }
}


案例2:


效果



servlet


public class ResponseDemo3 extends HttpServlet {
    /**
     * 输出图片
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        int width = 200;
        int height = 35;
        /**
         * 实现步骤:
         *  1.创建图像内存对象
         *  2.拿到画笔
         *  3.设置颜色,画矩形边框
         *  4.设置颜色,填充矩形
         *  5.设置颜色,画干扰线
         *  6.设置颜色,画验证码
         *  7.把内存图像输出到浏览器上
         */
        //创建内存图像
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//参数:宽度,高度 (指的都是像素),使用的格式(RGB)
        Graphics g = image.getGraphics();//画笔就一根
        //设置颜色
        g.setColor(Color.BLUE);
        //画边框
        g.drawRect(0, 0, width, height);
        //设置颜色
        g.setColor(Color.GRAY);
        //填充矩形
        g.fillRect(1, 1, width-2, height-2);
        //设置颜色
        g.setColor(Color.WHITE);
        //拿随机数对象
        Random r = new Random();
        //画干扰线 10条
        for(int i=0;i<10;i++){
            g.drawLine(r.nextInt(width), r.nextInt(height),r.nextInt(width), r.nextInt(height));
        }
        //设置颜色
        g.setColor(Color.RED);
        //改变字体大小
        Font font = new Font("宋体", Font.BOLD,30);//参数:1字体名称。2.字体样式 3.字体大小
        g.setFont(font);//设置字体
        //画验证码  4个
        int x = 35;//第一个数的横坐标是35像素
        for(int i=0;i<4;i++){
            //r.nextInt(10)+""这种写法效率是十分低的
            g.drawString(String.valueOf(r.nextInt(10)), x, 25);
            x+=35;
        }
        //输出到浏览器上
        //参数: 1.内存对象。2.输出的图片格式。3.使用的输出流
        ImageIO.write(image, "jpg", response.getOutputStream());
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}


相关文章
|
3月前
|
存储 前端开发 JavaScript
基于JavaWeb实现停车场管理系统
基于JavaWeb实现停车场管理系统
|
3月前
|
前端开发 JavaScript Java
图书借阅管理平台|基于JavaWeb实现图书借阅系统
图书借阅管理平台|基于JavaWeb实现图书借阅系统
|
3月前
|
前端开发 Java 关系型数据库
JavaWeb开发简介
JavaWeb开发简介
39 0
|
16天前
|
搜索推荐 Java 程序员
在Java编程的旅程中,条件语句是每位开发者不可或缺的伙伴,它如同导航系统,引导着程序根据不同的情况做出响应。
在Java编程中,条件语句是引导程序根据不同情境作出响应的核心工具。本文通过四个案例深入浅出地介绍了如何巧妙运用if-else与switch语句。从基础的用户登录验证到利用switch处理枚举类型,再到条件语句的嵌套与组合,最后探讨了代码的优化与重构。每个案例都旨在帮助开发者提升编码效率与代码质量,无论是初学者还是资深程序员,都能从中获得灵感,让自己的Java代码更加优雅和专业。
11 1
|
3月前
|
Java 开发者
深入Java多态:从“一个消息”到“多种响应”的进化之路
【6月更文挑战第17天】Java多态性简化教育软件开发:通过抽象Course类定义teach()方法,子类如MathCourse、EnglishCourse和ScienceCourse重写该方法,实现特定教学内容。在CourseManagementSystem中,多态允许通过Course引用调用不同课程的teach(),展示“一个消息,多种响应”的能力,增强代码灵活性和可维护性,是面向对象编程的关键。
21 2
|
3月前
|
SQL Java 数据库连接
JavaWeb Mapper代理开发
JavaWeb Mapper代理开发
|
2月前
|
存储 程序员
JavaWeb之Listener监听器
JavaWeb之Listener监听器
31 0
|
3月前
|
存储 NoSQL Java
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
Redis系列学习文章分享---第三篇(Redis快速入门之Java客户端--短信登录+session+验证码+拦截器+登录刷新)
59 0
|
3月前
|
前端开发 JavaScript 算法
javaweb(四)——过滤器与监听器
javaweb(四)——过滤器与监听器
|
3月前
|
存储 JSON 前端开发
JavaWeb中用来定义统一的响应结果的result类
JavaWeb中用来定义统一的响应结果的result类
55 0
下一篇
云函数使用