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

  • 相关阅读:
    sfs2x 连接 mongodb
    java websocket
    webstorm 4.0 注册码
    解决 sfs2 admin tool 找不到扩展
    window 注册表五大类
    opengl 学习第二日
    java google Protobuf
    扩展 java sencha touch PhonegapPlugin
    sencha touch2 kryonet socket phonegap 通信 作者:围城
    sencha touch2 layout 笔记
  • 原文地址:https://www.cnblogs.com/jinyu59/p/10837114.html
Copyright © 2011-2022 走看看