验证码校验
代码以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
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号