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


相关文章
|
1月前
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
230 5
|
2月前
|
前端开发 Java 数据库连接
【潜意识Java】深度解读JavaWeb开发在Java学习中的重要性
深度解读JavaWeb开发在Java学习中的重要性
48 4
|
4月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
100 6
|
5月前
|
JSON 前端开发 Java
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
文章介绍了Java后端如何使用Spring Boot框架响应不同格式的数据给前端,包括返回静态页面、数据、HTML代码片段、JSON对象、设置状态码和响应的Header。
238 1
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
|
6月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
574 37
|
5月前
|
前端开发 Java 应用服务中间件
Javaweb学习
【10月更文挑战第1天】Javaweb学习
52 2
|
6月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
|
5月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
196 5
|
5月前
|
Java
Java 登录输入的验证码
Java 登录输入的验证码
62 1
|
6月前
|
安全 Java Android开发
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
JavaWeb解压缩漏洞之ZipSlip与Zip炸弹
186 2