zoukankan      html  css  js  c++  java
  • javaWeb实现验证码--代码超简单

    方法一:

    1、前端显示

    HTML:

    <h3>验证码:</h3>
    <input type="text" name="validationCode" id="validationCode" placeholder="请输入验证码" lay-verify="required"> 
    <img src="validate.jsp" id="validationCode_img" title="看不清?换一个" onclick="loadimage();return false;" name="validationCode_img" align="middle">

    JS:

    //加载验证码图片,后面加时间可以保证每次页面刷新时验证码也刷新
    function loadimage(){
                document.getElementById("validationCode_img").src= "validate.jsp?time=" + new Date().getTime();
            }

    2、用一个页面生成验证码图片,这里我用JSP页面validate.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@page import="java.awt.image.BufferedImage"%>
    <%@page import="java.awt.Graphics2D"%>
    <%@page import="java.awt.Color"%>
    <%@page import="java.awt.Font"%>
    <%@page import="javax.imageio.ImageIO"%>
    <%@page import="java.util.Random"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>验证码</title>
    </head>
    <body>
    <%
        int width = 60;
        int height = 20;
        // 创建具有可访问图像数据缓冲区的Image
        BufferedImage buffImg = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffImg.createGraphics();
        
        // 创建一个随机数生成器
        Random random = new Random();
        
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
        
        // 创建字体,字体的大小应该根据图片的高度来定
        Font font = new Font("Times New Roman", Font.PLAIN, 18);
        // 设置字体
        g.setFont(font);
        
        // 画边框
        g.setColor(Color.BLACK);
        g.drawRect(0, 0, width - 1, height - 1);
        
        // 随机产生160条干扰线
        g.setColor(Color.LIGHT_GRAY);
        for (int i = 0; i < 160; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(12);
            int y1 = random.nextInt(12);
            g.drawLine(x, y, x + x1, y + y1);
        }
        
        // randomCode 用于保存随机产生的验证码
        StringBuffer randomCode = new StringBuffer();
        int red = 0, green = 0, blue = 0;
        
        // 随机产生4位数字的验证码
        for (int i = 0; i < 4; i++) {
            // 得到随机产生的验证码数字
            String strRand = String.valueOf(random.nextInt(10));
        
            // 产生随机的颜色分量来构造颜色值
            red = random.nextInt(110);
            green = random.nextInt(50);
            blue = random.nextInt(50);
        
            // 用随机产生的颜色将验证码绘制到图像中
            g.setColor(new Color(red, green, blue));
            g.drawString(strRand, 13 * i + 6, 16);
        
            randomCode.append(strRand);
        }
        
        // 将四位数字的验证码保存到session中
        //HttpSession session = request.getSession();
        session.setAttribute("randomCode", randomCode.toString());
        
        // 禁止图像缓存
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        
        response.setContentType("image/jpeg");
        // 将图像输出到servlet输出流中
        ServletOutputStream sos = response.getOutputStream();
        ImageIO.write(buffImg, "jpeg", sos);
        sos.close();
        //sos = null;
        out.clear();
        out = pageContext.pushBody();
    %>
    </body>
    </html>

    3、在validate.jsp页面中生成的验证码其实就是在java后端生成的,所以就存进了session中,我们只需要在用户提交的时候将填写的验证码带到后端,这里我使用的是ajax请求,后端只需要判断验证码是否和session中一样就可以了。

     方法二:

     html代码:

    <div class="layui-form-item">
         <div class="layui-inline">
               <input type="text" name="verity" required lay-verify="required" placeholder="验证码" autocomplete="off" class="layui-input">
         </div>
         <div class="layui-inline">
              <img class="verifyImg" id="verifyImg" onclick="javascript:getvCode();"  />
              <script type="text/javascript">
                      getvCode();//初始化验证码,写在此处减少验证码图片出来的延时
              </script>
         </div>
    </div>

    js代码:

    /**
     * 获取验证码
     * 将验证码写到login.html页面的id = verifyimg 的地方
     */
    function getvCode() {
        $("#verifyImg").attr('src',timestamp("verifyCode"));
        
        
    }
    //为url添加时间戳
     function timestamp(url) {
        var getTimestamp = new Date().getTime();
        if (url.indexOf("?") > -1) {
            url = url + "&timestamp=" + getTimestamp
        } else {
            url = url + "?timestamp=" + getTimestamp
        }
        return url;
    };

    java代码:

    model层

    //验证码
    public class VerifyCode {
        private String code;
        private byte[] imgBytes;
        private long expireTime;
        public String getCode() {
            return code;
        }
        public void setCode(String code) {
            this.code = code;
        }
        public byte[] getImgBytes() {
            return imgBytes;
        }
        public void setImgBytes(byte[] imgBytes) {
            this.imgBytes = imgBytes;
        }
        public long getExpireTime() {
            return expireTime;
        }
        public void setExpireTime(long expireTime) {
            this.expireTime = expireTime;
        }
    }

    service层

    import java.io.IOException;
    import java.io.OutputStream;
    
    import com.hongyang.webglasses.model.VerifyCode;
    
    //验证码生成接口
    public interface IVerifyCodeGen {
        /**
         * 生成验证码并返回code,将图片写的os中
         *
         * @param width
         * @param height
         * @param os
         * @return
         * @throws IOException
         */
        String generate(int width, int height, OutputStream os) throws IOException;
     
        /**
         * 生成验证码对象
         *
         * @param width
         * @param height
         * @return
         * @throws IOException
         */
        VerifyCode generate(int width, int height) throws IOException;
    }

    serviceimpl实现

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Service;
    
    import com.hongyang.webglasses.model.VerifyCode;
    import com.hongyang.webglasses.service.IVerifyCodeGen;
    import com.hongyang.webglasses.util.RandomUtils;
    
    @Service
    public class SimpleCharVerifyCodeGenImpl implements IVerifyCodeGen {
        private static final Logger logger = LoggerFactory.getLogger(SimpleCharVerifyCodeGenImpl.class);
        private static final String[] FONT_TYPES = { "u5b8bu4f53", "u65b0u5b8bu4f53", "u9ed1u4f53", "u6977u4f53", "u96b6u4e66" };
        private static final int VALICATE_CODE_LENGTH = 4;
        
        /**
         * 生成随机字符
         *
         * @param width
         * @param height
         * @param os
         * @return
         * @throws IOException
         */
        @Override
        public String generate(int width, int height, OutputStream os) throws IOException {
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics graphics = image.getGraphics();
            fillBackground(graphics, width, height);
            String randomStr = RandomUtils.randomString(VALICATE_CODE_LENGTH);
            createCharacter(graphics, randomStr);
            graphics.dispose();
            //设置JPEG格式
            ImageIO.write(image, "JPEG", os);
            return randomStr;
        }
    
        /**
         * 验证码生成
         *
         * @param width
         * @param height
         * @return
         */
        @Override
        public VerifyCode generate(int width, int height) {
            VerifyCode verifyCode = null;
            try (
                    //将流的初始化放到这里就不需要手动关闭流
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ) {
                String code = generate(width, height, baos);
                verifyCode = new VerifyCode();
                verifyCode.setCode(code);
                verifyCode.setImgBytes(baos.toByteArray());
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
                verifyCode = null;
            }
            return verifyCode;
        }
    
        /**
         * 设置字符颜色大小
         *
         * @param g
         * @param randomStr
         */
        private void createCharacter(Graphics g, String randomStr) {
            char[] charArray = randomStr.toCharArray();
            for (int i = 0; i < charArray.length; i++) {
                //设置RGB颜色算法参数
                g.setColor(new Color(50 + RandomUtils.nextInt(100),
                        50 + RandomUtils.nextInt(100), 50 + RandomUtils.nextInt(100)));
                //设置字体大小,类型
                g.setFont(new Font(FONT_TYPES[RandomUtils.nextInt(FONT_TYPES.length)], Font.BOLD, 26));
                //设置x y 坐标
                g.drawString(String.valueOf(charArray[i]), 15 * i + 5, 19 + RandomUtils.nextInt(8));
            }
        }
        
        /**
         * 设置背景颜色及大小,干扰线
         *
         * @param graphics
         * @param width
         * @param height
         */
        private static void fillBackground(Graphics graphics, int width, int height) {
            // 填充背景
            System.setProperty("myColor", "#BBDAEE");
            graphics.setColor(Color.getColor("myColor"));
            //设置矩形坐标x y 为0
            graphics.fillRect(0, 0, width, height);
    
            // 加入干扰线条
            for (int i = 0; i < 8; i++) {
                //设置随机颜色算法参数
                graphics.setColor(RandomUtils.randomColor(40, 150));
                Random random = new Random();
                int x = random.nextInt(width);
                int y = random.nextInt(height);
                int x1 = random.nextInt(width);
                int y1 = random.nextInt(height);
                graphics.drawLine(x, y, x1, y1);
            }
        }
    }

    Controller层

    @GetMapping("/verifyCode")
        public void verifyCode(HttpServletRequest request, HttpServletResponse response) {
            IVerifyCodeGen iVerifyCodeGen = new SimpleCharVerifyCodeGenImpl();
            try {
                //设置长宽
                VerifyCode verifyCode = iVerifyCodeGen.generate(80, 28);
                String code = verifyCode.getCode();
                //将VerifyCode绑定session,登录控制器可从session中取出从而判断用户填的验证码是否正确
                request.getSession().setAttribute("VerifyCode", code);
                //设置响应头
                response.setHeader("Pragma", "no-cache");
                //设置响应头
                response.setHeader("Cache-Control", "no-cache");
                //在代理服务器端防止缓冲
                response.setDateHeader("Expires", 0);
                //设置响应内容类型
                response.setContentType("image/jpeg");
                response.getOutputStream().write(verifyCode.getImgBytes());
                response.getOutputStream().flush();
            } catch (IOException e) {
            }
        }

    工具类

    import java.awt.Color;
    import java.util.Random;
    
    //生成验证码随机字符
    public class RandomUtils extends org.apache.commons.lang3.RandomUtils{
        private static final char[] CODE_SEQ = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',
                'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
                'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9' };
     
        private static final char[] NUMBER_ARRAY = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
     
        private static Random random = new Random();
     
        public static String randomString(int length) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < length; i++) {
                sb.append(String.valueOf(CODE_SEQ[random.nextInt(CODE_SEQ.length)]));
            }
            return sb.toString();
        }
     
        public static String randomNumberString(int length) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < length; i++) {
                sb.append(String.valueOf(NUMBER_ARRAY[random.nextInt(NUMBER_ARRAY.length)]));
            }
            return sb.toString();
        }
     
        public static Color randomColor(int fc, int bc) {
            int f = fc;
            int b = bc;
            Random random = new Random();
            if (f > 255) {
                f = 255;
            }
            if (b > 255) {
                b = 255;
            }
            return new Color(f + random.nextInt(b - f), f + random.nextInt(b - f), f + random.nextInt(b - f));
        }
     
        public static int nextInt(int bound) {
            return random.nextInt(bound);
        }
    }

     效果图:

  • 相关阅读:
    jzoj 6278. 2019.8.5【NOIP提高组A】跳房子
    2019.08.05【NOIP提高组】模拟 A 组 总结
    HTML笔记
    html中的锚点设置
    前端HTML
    数据库设计(第一范式,第二范式,第三范式)
    MySQL之锁、事务、优化、OLAP、OLTP
    MySQL数据备份与还原(mysqldump)
    MySQl创建用户和授权
    MySQL之索引原理与慢查询优化
  • 原文地址:https://www.cnblogs.com/qiantao/p/11850956.html
Copyright © 2011-2022 走看看