验证码

  • 原理
    第一:首先在服务器端生成一个n个字符的字符串,然后保存到session,并将这个字符串转换成img图片,传递到浏览器端
    第二:用户根据浏览器端显示的验证码图片,输入对应的字符,提交表单
    第三:在服务端将用户提交的验证码字符【request域】和session服务端保存的验证码进行比较,
    如果相等,就认为验证码输入正确,然后就可以验证用户名和密码是否正确,
    如果用户名和密码正确:就允许登录,同时将用户信息保存到session中
    如果用户名和密码不正确,直接重定向到登录页面。
    如果不相等直接重定向到登录页面。
  • 验证码代码
package com.ujiuye.common;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * 验证码工具类
 */
public class ValidateCode {

    private int width = 90;//验证码宽度 默认值:90
    private int height = 40;//验证码高度 默认值:40
    private int codeCount = 4;//验证码个数  默认值:4
    private int lineCount = 19;//混淆线个数  默认值:19
    private int fontSize = 20;//字体大小像素
    //存储session中的key值 默认值:"validateCode"
    private String sessionKey = "validateCode";

    public ValidateCode() {
    }

    /**
     * @param width    验证码宽度
     * @param height   验证码高度
     * @param fontSize 字体大小像素
     */
    public ValidateCode(int width, int height, int fontSize) {
        this.width = width;
        this.height = height;
        this.fontSize = fontSize;
    }

    /**
     * @param width      验证码宽度
     * @param height     验证码高度
     * @param fontSize   字体大小像素
     * @param sessionKey 存储session中的key值
     */
    public ValidateCode(int width, int height, int fontSize, String sessionKey) {
        this.width = width;
        this.height = height;
        this.fontSize = fontSize;
        this.sessionKey = sessionKey;
    }

    /**
     * @param width      验证码宽度
     * @param height     验证码高度
     * @param codeCount  验证码个数
     * @param fontSize   字体大小像素
     * @param sessionKey 存储session中的key值
     */
    public ValidateCode(int width, int height, int codeCount, int fontSize, String sessionKey) {
        this.width = width;
        this.height = height;
        this.codeCount = codeCount;
        this.fontSize = fontSize;
        this.sessionKey = sessionKey;
    }

    /**
     * @param width      验证码宽度
     * @param height     验证码高度
     * @param codeCount  验证码个数
     * @param lineCount  混淆线个数
     * @param fontSize   字体大小像素
     * @param sessionKey 存储session中的key值
     */
    public ValidateCode(int width, int height, int codeCount, int lineCount, int fontSize, String sessionKey) {
        this.width = width;
        this.height = height;
        this.codeCount = codeCount;
        this.lineCount = lineCount;
        this.fontSize = fontSize;
        this.sessionKey = sessionKey;
    }


    char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /**
     * 具体获取验证码的方法
     *
     * @param time time为时戳,这样的话可以避免浏览器缓存验证码
     * @throws IOException
     */
    public void getCode(HttpServletRequest request, HttpServletResponse response) {
        //定义随机数类
        Random r = new Random();
        //定义存储验证码的类
        StringBuilder builderCode = new StringBuilder();
        //定义画布
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //得到画笔
        Graphics g = buffImg.getGraphics();
        //1.设置颜色,画边框
        g.setColor(Color.gray);
        g.drawRect(0, 0, width, height);
        //2.设置颜色,填充内部
        g.setColor(Color.white);
        g.fillRect(1, 1, width - 2, height - 2);
        //3.设置干扰线
        // g.setColor(Color.gray);
        for (int i = 0; i < lineCount; i++) {
            int _R = (int) Math.floor(Math.random() * 256);
            int _G = (int) Math.floor(Math.random() * 256);
            int _B = (int) Math.floor(Math.random() * 256);
            g.setColor(new Color(_R, _G, _B, 255));
            g.drawLine(r.nextInt(width), r.nextInt(width), r.nextInt(width), r.nextInt(width));
        }
        //4.设置验证码
        g.setColor(Color.blue);
        //4.1设置验证码字体
        g.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, fontSize));
        for (int i = 0; i < codeCount; i++) {
            char c = codeSequence[r.nextInt(codeSequence.length)];
            builderCode.append(c);
            g.drawString(c + "", ((width / codeCount) * i + 2), height * 4 / 5);
        }
        try {
            //5.输出到屏幕
            ServletOutputStream sos = response.getOutputStream();
            ImageIO.write(buffImg, "png", sos);
            //6.保存到session中
            HttpSession session = request.getSession();
            session.setAttribute("" + sessionKey + "", builderCode.toString());
            //7.禁止图像缓存。
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/png");
            //8.关闭sos
            sos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 



  • 调用过程
package com.ujiuye.sys.bean;

import com.ujiuye.common.ValidateCode;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@RequestMapping("/code")
public class ValidateCodeController {
    @RequestMapping(value = "getCode")
    public void getCode(@RequestParam(value = "time") String time, HttpServletRequest request, HttpServletResponse response) {
        ValidateCode code = new ValidateCode(100, 30, 4, 30, 25, "validateCode");
        code.getCode(request, response);

    }
}

前端:

<img id="image" src="${pageContext.request.contextPath}/code/getCode?time=false">
  • 登录示例
 /**
     * 如果在重定向的时候想携带数据到页面
     * 1、在目标方法参数上使用RedirectAttributes类型
     * 2、在使用RedirectAttributes的时候需要在springmvc.xml中配置
     * <mvc:view-controller path="/login" view-name="login"></mvc:view-controller>
     */

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(Employee employee, String code, HttpSession session, RedirectAttributes attributes){
        String validateCode = (String)session.getAttribute("validateCode");
        //用户输入的验证码和session中的验证码做比较
        if(code.equalsIgnoreCase(validateCode)){
            //验证码验证成功完使验证码失效
            session.removeAttribute("validateCode");
            employee=employeeService.login(employee);
            if (employee!=null){
                session.setAttribute("loginUser",employee);
                return "redirect:/index.jsp";
            }else{
                //重定向页面时将错误信息加载到页面
                attributes.addFlashAttribute("errorMsg","用户名或者密码错误");
                return "redirect:/login";

            }
        }
        //重定向页面时将错误信息加载到页面
        attributes.addFlashAttribute("errorMsg","验证码错误");
        return "redirect:/login";
    }
}

``

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值