web登录验证码生成

目的:实现在登录表单验证码的生成

声明:我是参考别人的例子,代码大部分也是引用的

原理:是在要显示验证码的地方用<img>,它的src指向了另一个生成验证码的jsp页面(用controller的url指向一个jsp页面),在生成验证码jsp页面的java代码里生成一张验证码图片

 

代码里注释已经非常详情,这里就不做多说了!

 

提交表单的登录页面 login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>登录</title>

    <%
        pageContext.setAttribute("APP_PATH",request.getContextPath());
    %>

    <script type="text/javascript">

        /*	刷新验证码	*/
        function change_yanzhengma()
        {
            // 这个src也可以用相对路径
            // 这个flag=Math.random()很关键,作用是每次传的值不同,才可以实现<img>的src的局部刷新,没有这个src不会变,
            // 因为请求参数一样,浏览器不会重新请求,这里每次传的参数不一样,浏览器就会每次发出请求,实际上后台并没有接受flag这个参数
            document.getElementById("checkcode_img").src = "changeCode?flag="+Math.random();
        }

        function checkLoginInfo()
        {
            if (form1.userName.value == "" || form1.userName.value == null)
            {
                alert("用户名不能为空");
                form1.userName.focus();
                return false;
            }
            else if (form1.userCode.value == "" || form1.userCode.value == null)
            {
                alert("验证码不能为空");
                form1.yanzhengma.focus();
                return false;
            }

            return true;
        }
    </script>

</head>
<body>
    <%--想要用js验证表单,返回false就不提交,必须要 onsubmit="return functionName();" 少了 return 一样会提交--%>
    <form action="loginCheck" method="post" name="form1" onsubmit="return checkLoginInfo();">
        请输入用户名:<input type="text" name="userName" id="userName"/>
        <br/>
        <%--src路径直接用controler指定的url,这个url是直接return一个jsp页面,那个页面没有边框只有图,直接显示在这里--%>
        <img title="刷新验证码" alt="刷新验证码" src="${APP_PATH}/changeCode" border="0" id="checkcode_img" onClick="change_yanzhengma();" />
        <br/>
        请输入验证码:<input type="text" name="code" />
        <br/>
        <input type="submit" value="确认登录">
        <br/>
        <!-- 保存登录失败时显示给用户的提示信息 -->
        <span color="red">
            <%--回显完信息,立即将session信息删除,防止重新刷新页面还看到这条信息--%>
            ${sessionScope.loginError } <%session.removeAttribute("loginError"); %>
        </span>
    </form>
</body>
</html>

生成验证码的 jsp页面 changeCode.jsp

<%@ page contentType="text/html;charset=gbk" language="java" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"%>
<%@ page import="java.io.OutputStream"%>


<%--	采用JPG格式的图片验证码	--%>

<%--这里之所以用声明语句块,是因为这是一个方法,java代码块编译后是放到servlet类的方法里面,方法里面不可以再有方法,会报错。
而声明语句块是编译后在servlet类里方法外,作为成员变量,可以声明一个方法--%>
<%!Color getRandColor(int fc, int bc)	//随机生成图片中rgb的值
{
    Random random = new Random();
    if (fc > 255)
        fc = 255;

    if (bc > 255)
        bc = 255;

    int r = fc + random.nextInt(bc - fc);

    int g = fc + random.nextInt(bc - fc);

    int b = fc + random.nextInt(bc - fc);

    return new Color(r, g, b);
}
%>

<%
    try
    {
        response.setHeader("Pragma", "No-cache");

        response.setHeader("Cache-Control", "no-cache");

        response.setDateHeader("Expires", 0);

        int width = 75, height = 30;

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        OutputStream os = response.getOutputStream();

        Graphics g = image.getGraphics();  // 画笔

        Random random = new Random();

        // 设置画笔的颜色
        g.setColor(getRandColor(200, 250));

        // 画图,生成干扰图片
        g.fillRect(0, 0, width, height);

        //字体等样式
        g.setFont(new Font("Times New Roman", Font.PLAIN, 25));

        g.setColor(getRandColor(160, 200));
        //生成图像内部的干扰线条
        for (int i = 0; i < 155; i++)
        {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);

            //绘制干扰线条
            g.drawLine(x, y, x + xl, y + yl);
        }

        String sRand = "";
        //生成4个随机的、有彩色的验证码
        for (int i = 0; i < 4; i++)
        {
            //生成一位验证码的值
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;

            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));

            //把生成的验证码值画进图对象里,后面两个参数是生成的位置
            g.drawString(rand, 14 * i + 11, 23);
        }

        session.setAttribute("code_inSession", sRand);

        g.dispose();

        //生成JPEG格式的图片验证码
        ImageIO.write(image, "gif", os);

        os.flush();
        os.close();

        os = null;

        // 用来将缓冲区的数据立即输出到浏览器当中
        response.flushBuffer();

        /*	两句关键代码	*/
        out.clear();

        out = pageContext.pushBody();
    }
    catch (IllegalStateException e)
    {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
%>

controller部分代码

// 验证码登录页面
    @RequestMapping("/loginPage")
    public String loginPage1(){
        return "login_code/login";
    }

    // 更新验证码,换验证码
    @RequestMapping("/changeCode")
    public String checkcode(){
        return "login_code/changeCode";
    }

    // 验证验证码是否正确
    @RequestMapping("/loginCheck")
    public String loginCheck(String username,String code, HttpServletRequest request,HttpServletResponse response){
        HttpSession session = request.getSession();
        // 获取session里的验证码,然后删除
        String sessionCode = (String)session.getAttribute("code_inSession");
        session.removeAttribute("code_inSession");
        if (!code.equals(sessionCode))
        {
            // 验证码错误
            session.setAttribute("loginError", "验证码错误");
            // 重定向,redirect: 后面跟controller的url路径,不同controller也可以,记得要加 /
            // 请求转发,forward: 用法一样     用重定向是防止表单重复提交的简单解决方法
            return "redirect:/loginPage";
        }else
        {
            //用户名密码验证

            return "redirect:/main";
        }
    }

    @RequestMapping("/main")
    public String mainPage(){
        return "login_code/main";
    }

最后给一个简单的验证通过页面 main.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>main页面</title>
</head>
<body>
验证成功!
</body>
</html>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值