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

     效果图:

  • 相关阅读:
    ajax专题
    luogu P1346 电车 最短路
    luogu P1462 通往奥格瑞玛的道路 最短路
    luogu P1328 生活大爆炸版石头剪刀布
    luogu P1315 联合权值 枚举
    luogu P1156 垃圾陷阱 背包问题
    luogu P1217 回文质数 枚举
    luogu P3650 滑雪课程设计 枚举
    luogu1209 修理牛棚 贪心
    luogu P1223 排队接水 贪心
  • 原文地址:https://www.cnblogs.com/qiantao/p/11850956.html
Copyright © 2011-2022 走看看