zoukankan      html  css  js  c++  java
  • 项目总结16-创建验证码图片

    创建验证码图片

    前言

      基本上,自己接手的项目,只要有用户概念,就有登陆,只要有登陆页面,就可能会用到验证码,今天刚好有时间,便整理下验证码创建的前后端过程

    关键字

      SecurityUtils  BufferedImage  Rectangle2D 

    正文

    1-验证码逻辑分析

      系统自动生成4位(或6位)随机验证码code,于此同时,做两件事:(1)将code绘制成图片,在前端展示给用户看,(2)将code保存在session中,用于用户输入验证码时进行校验

    2-代码分析

    2-1-前端代码

    <div style="float: left;70px;">
        <img style="height:25px;70px;margin-top:7px;margin-left:-20px;" id="codeImg" alt="点击更换"
            title="点击更换" src="" />
    </div>
    
    //页面初始化时
    $(document).ready(function() {
        changeCode();//加载验证码
        $("#codeImg").bind("click", changeCode);//绑定点击事件
    });
    
    //改变验证码
    function changeCode() {
        $("#codeImg").attr("src", "code.do?t=" + genTimestamp());
    }

    2-2-后台代码

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.font.FontRenderContext;
    import java.awt.geom.Rectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.hs.common.util.Logger;
    import com.hs.web.boot.util.SecurityUtils;
    
    @Controller
    @RequestMapping("/code")
    public class SecCodeController {
        
        private static Logger logger = Logger.getLogger(SecCodeController.class);
        //1-接口:创建验证码图片并返回
        @RequestMapping
        public void generate(HttpServletResponse response){
            //1-创建验证码图片
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            String code = drawImg(output);
            //2-将验证码保存在redis的session中
            Subject currentUser = SecurityUtils.getSubject();  
            Session session = currentUser.getSession();
            session.setAttribute("sessionSecCode", code);
            
            try {
                //3-返回验证码图片
                ServletOutputStream out = response.getOutputStream();
                output.writeTo(out);
            } catch (IOException e) {
                logger.warn(e);
            }
        }
        
        //2-子方法:生成验证码图片
        private String drawImg(ByteArrayOutputStream output){
            String code = "";
            //1-随机生成4位数验证码,大写字母+数字
            for(int i=0; i<4; i++){
                code += randomChar();
            }
            //2-设置图片的宽高
            int width = 70;
            int height = 25;
            //3-创建一个BufferedImage图片缓冲对象
            BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);//第三个参数表示图像字节灰度图像
            //4-获取Graphics2D对象,用在底图对象上绘图
            Graphics2D g = bi.createGraphics();
            //5-设置绘图内容的字体、颜色,背景色、
            Font font = new Font("Times New Roman",Font.PLAIN,20);
            g.setFont(font);
            Color color = new Color(66,2,82);
            g.setColor(color);
            g.setBackground(new Color(226,226,240));
            //6-在缓冲图片内清空一个矩形区域,用于绘制验证码区域
            g.clearRect(0, 0, width, height);
            FontRenderContext context = g.getFontRenderContext();
            Rectangle2D bounds = font.getStringBounds(code, context);
            //7-计算code的开始位置
            double x = (width - bounds.getWidth()) / 2;
            double y = (height - bounds.getHeight()) / 2;
            double ascent = bounds.getY();
            double baseY = y - ascent;
            //8-code在图片上的位置是((int)x, (int)baseY)
            g.drawString(code, (int)x, (int)baseY);
            g.dispose();
            try {
                ImageIO.write(bi, "jpg", output);
            } catch (IOException e) {
                logger.warn(e);
            }
            return code;
        }
        //3-随机字符串
        private char randomChar(){
            Random r = new Random();
            String s = "ABCDEFGHJKLMNPRSTUVWXYZ0123456789";//字符限定于大写字母和数字
            return s.charAt(r.nextInt(s.length()));
        }
    }

    3-效果示例

     

  • 相关阅读:
    awk应用
    字符串应用,expect预期交互,数组,正则表达式
    for,while循环,case分支,shell函数
    数值运算,if结构
    shell基础应用,变量的扩展应用
    rsync基本用法与配置,split分离解析
    PXE自动装机
    配置DNS服务器
    进程查看,终止
    应用技巧,vim用法,编译安装软件包
  • 原文地址:https://www.cnblogs.com/wobuchifanqie/p/10274136.html
Copyright © 2011-2022 走看看