zoukankan      html  css  js  c++  java
  • 验证码校验

    代码以SpringBoot+ThymeLeaf为例

    验证码校验基本都是套路操作,各种工具用法都大差不差.记住套路即可

    验证码工具类源代码会放在文章最后.

    JavaWeb实现验证码校验

    1.下载验证码生成工具(源代码在文章最后),再放入项目中

    2.HTML代码

    验证码 : <img th:src="@{/verifyCode}" onclick="this.src='/verifyCode?d=' + Math.random()"/>
    输入验证码 : <input name="verifyText" type="text">
    <!--在form表单中-->
    <!--点击事件中,src记得加上随机数防止缓存-->
    

    3.Controller层写法

    //自动注入验证码生成工具,不要忘了在工具类上加@Component
    @Autowired
    VerifyCode vc;
    
    //........其他代码
    
    @RequestMapping("/verifyCode")
    public void verifyCode(HttpServletRequest request, HttpServletResponse response) throws IOException{
    
        //response设置禁止缓存
        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        //byte数组和两种输出流
        byte[] imageByte;
        ByteArrayOutputStream bytesOutputStream = null;
        ServletOutputStream responseOutputStream = null;
        //先获取图像,再获取验证码(顺序不要错)
        BufferedImage image = vc.getImage();
        String verifyText = vc.getText();
        verifyText.toUpperCase();
        //把文本写入Session
        request.getSession().setAttribute("verifyText", verifyText);
        try{
            //创建ByteArrayOutputStream和ResponseOutputStream
            bytesOutputStream = new ByteArrayOutputStream();
            responseOutputStream = response.getOutputStream();
            //把验证码图像写入bytes输出流
            ImageIO.write(image, "JPEG", bytesOutputStream);
            //获取byte数组
            imageByte = bytesOutputStream.toByteArray();
            //将byte数组写入reponse输出流
            responseOutputStream.write(imageByte);
            responseOutputStream.flush();
        }finally{
            //关闭输出流
            responseOutputStream.close();
            bytesOutputStream.close();
        }
    
    }

      注意 : 不要设置跳转地址,原路返回即可!

    4.注册账号的Controller

    @RequestMapping("/createUser")
    public String createUser(User user, String verifyText, Model m, HttpServletRequest request){
        //校验验证码
        HttpSession session = request.getSession();
        String vfText_session = (String)session.getAttribute("verifyText");
        verifyText.toUpperCase();
        if(!vfText_session.equals(verifyText)){
            m.addAttribute("info", "验证码错误");
            return "regist";
        }else{
            session.removeAttribute("verifyText");
        }
        //注册流程省略......
    }

    至此就完成了验证码校验

    BufferedImage类和ImageIO类

     BufferedImage :

      用于在内存中保存图片

      验证码工具生成的图像就是一个BufferedImage对象,

    ImageIO : 

      public static boolean write(RenderedImage im, String formatName, OutputStream output)

      给write()方法传入(BufferedImage对象, 图像格式,  ByteArrayOutputStream输出流),

      把图像写入到ByteArrayOutputStream输出流中,在用ByteArrayOutputStream的toByteArray()方法

      得到byte数组,再把byte数组写入到reponse的输出流中就完事了!

    验证码生成工具源码

    我这次练习中使用的是

    package com.jy.test.utils;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Repository;
    
    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Random;
    import javax.imageio.ImageIO;
    @Component
    public class VerifyCode {
        private int w = 70;
        private int h = 35;
        private Random r = new Random();
        // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
        private String[] fontNames  = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};
        // 可选字符
        private String codes  = "0123456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
        // 背景色
        private Color bgColor  = new Color(255, 255, 255);
        // 验证码上的文本
        private String text ;
    
        // 生成随机的颜色
        private Color randomColor () {
            int red = r.nextInt(150);
            int green = r.nextInt(150);
            int blue = r.nextInt(150);
            return new Color(red, green, blue);
        }
    
        // 生成随机的字体
        private Font randomFont () {
            int index = r.nextInt(fontNames.length);
            String fontName = fontNames[index];//生成随机的字体名称
            int style = r.nextInt(4);//生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
            int size = r.nextInt(5) + 24; //生成随机字号, 24 ~ 28
            return new Font(fontName, style, size);
        }
    
        // 画干扰线
        private void drawLine (BufferedImage image) {
            int num  = 3;//一共画3条
            Graphics2D g2 = (Graphics2D)image.getGraphics();
            for(int i = 0; i < num; i++) {//生成两个点的坐标,即4个值
                int x1 = r.nextInt(w);
                int y1 = r.nextInt(h);
                int x2 = r.nextInt(w);
                int y2 = r.nextInt(h);
                g2.setStroke(new BasicStroke(1.5F));
                g2.setColor(Color.BLUE); //干扰线是蓝色
                g2.drawLine(x1, y1, x2, y2);//画线
            }
        }
    
        // 随机生成一个字符
        private char randomChar () {
            int index = r.nextInt(codes.length());
            return codes.charAt(index);
        }
    
        // 创建BufferedImage
        private BufferedImage createImage () {
            BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = (Graphics2D)image.getGraphics();
            g2.setColor(this.bgColor);
            g2.fillRect(0, 0, w, h);
            return image;
        }
    
        // 调用这个方法得到验证码
        public BufferedImage getImage () {
            BufferedImage image = createImage();//创建图片缓冲区
            Graphics2D g2 = (Graphics2D)image.getGraphics();//得到绘制环境
            StringBuilder sb = new StringBuilder();//用来装载生成的验证码文本
            // 向图片中画4个字符
            for(int i = 0; i < 4; i++)  {//循环四次,每次生成一个字符
                String s = randomChar() + "";//随机生成一个字母
                sb.append(s); //把字母添加到sb中
                float x = i * 1.0F * w / 4; //设置当前字符的x轴坐标
                g2.setFont(randomFont()); //设置随机字体
                g2.setColor(randomColor()); //设置随机颜色
                g2.drawString(s, x, h-5); //画图
            }
            this.text = sb.toString(); //把生成的字符串赋给了this.text
            drawLine(image); //添加干扰线
            return image;
        }
    
        // 返回验证码图片上的文本
        public String getText () {
            return text;
        }
    
        // 保存图片到指定的输出流
        public static void output (BufferedImage image, OutputStream out)
                throws IOException {
            ImageIO.write(image, "JPEG", out);
        }
    }
    

      

    以上

    f

  • 相关阅读:
    通过xshell在本地win主机和远程linux主机传输文件
    CentOS7.4搭建ftp服务
    CentOS7.4中配置jdk环境
    spring AOP学习笔记
    java代码连接oracle数据库的方法
    通过xshell上传和下载文件
    java设计模式简述
    本地项目文件通过git提交到GitHub上
    centos7中oracle数据库安装和卸载
    centos7远程服务器中redis的安装与java连接
  • 原文地址:https://www.cnblogs.com/jinyu59/p/10837114.html
Copyright © 2011-2022 走看看