springMVC+Java验证码完善注册功能

Wesley13
• 阅读 593

这篇文章简单的写了一个java验证码,为之前写过的springMVC注册功能加上验证码,验证码的作用就不多说了,防止机器人程序恶意注册什么的。。。

基本的注册功能的实现请查看之前的文章Maven搭建springMVC+spring+hibernate实现用户注册

其中,我修改了该注册程序的部分代码,其中User.java,加上了password和code的属性,同时将password持久到数据库,code属性使用@transient注解使其不被持久到数据库。

User.java 中加上这两个属性,至于User的构造方法修改为public User(String id, Date regtime, String username,String password) 就不贴代码了。

private String password;
    @Column(name="password",nullable=false,length=20)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    private String code;
    @Transient   //不需要持久到DB的属性使用该注解
    public String getCode() {
        return code;
    }
    
    public void setCode(String code) {
        this.code = code;
    }

下面是验证码生成的controller,大部分代码都写上了注释。

CodeController.java

package com.sgl.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CodeController {
    private int width = 90;//定义图片的width
    private int height = 20;//定义图片的height
    private int codeCount = 4;//定义图片上显示验证码的个数
    private int xx = 15;
    private int fontHeight = 18;
    private int codeY = 16;
    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' };

    @RequestMapping("/code")
    public void getCode(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {

        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
//        Graphics2D gd = buffImg.createGraphics();
        //Graphics2D gd = (Graphics2D) buffImg.getGraphics();
        Graphics gd = buffImg.getGraphics();
        // 创建一个随机数生成器类
        Random random = new Random();
        // 将图像填充为白色
        gd.setColor(Color.WHITE);
        gd.fillRect(0, 0, width, height);

        // 创建字体,字体的大小应该根据图片的高度来定。
        Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
        // 设置字体。
        gd.setFont(font);

        // 画边框。
        gd.setColor(Color.BLACK);
        gd.drawRect(0, 0, width - 1, height - 1);

        // 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。
        gd.setColor(Color.BLACK);
        for (int i = 0; i < 40; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }

        // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
        StringBuffer randomCode = new StringBuffer();
        int red = 0, green = 0, blue = 0;

        // 随机产生codeCount数字的验证码。
        for (int i = 0; i < codeCount; i++) {
            // 得到随机产生的验证码数字。
            String code = String.valueOf(codeSequence[random.nextInt(36)]);
            // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);

            // 用随机产生的颜色将验证码绘制到图像中。
            gd.setColor(new Color(red, green, blue));
            gd.drawString(code, (i + 1) * xx, codeY);

            // 将产生的四个随机数组合在一起。
            randomCode.append(code);
        }
        // 将四位数字的验证码保存到Session中。
        HttpSession session = req.getSession();
        System.out.print(randomCode);
        session.setAttribute("code", randomCode.toString());

        // 禁止图像缓存。
        resp.setHeader("Pragma", "no-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);

        resp.setContentType("image/jpeg");

        // 将图像输出到Servlet输出流中。
        ServletOutputStream sos = resp.getOutputStream();
        ImageIO.write(buffImg, "jpeg", sos);
        sos.close();
    }

}

改写UserController.java中的注册代码

将UserController.java中add方法修改为下面这样。

@RequestMapping("/user")
    public ModelAndView addUser(User user,HttpSession session) {
        ModelAndView mav=new ModelAndView();
        if (!(user.getCode().equalsIgnoreCase(session.getAttribute("code").toString()))) {  //忽略验证码大小写
            mav.setViewName("error");
            mav.addObject("msg","验证码不正确");
            return mav;
        }else {
            user.setId(UUID.randomUUID().toString());
            user.setRegtime(new Date());
            try {
                userService.addUser(user);
            //    request.setAttribute("user", user);
                mav.setViewName("success");
                mav.addObject("user", user);
                mav.addObject("msg", "注册成功了,可以去登陆了");
                return mav;
            } catch (Exception e) {
                mav.setViewName("menu");
                mav.addObject("user", null);
                mav.addObject("msg", "注册失败");
                return mav;
            }
        }
    }

然后就是修改前台页面了

将注册的index.jsp的form修改

<form action="user.html" method="post">
 <table width="207" border="0" align="center">
        <tr>
          <td colspan="2" align="center" nowrap="nowrap">用户注册</td>
        </tr>
        <tr>
          <td width="68" nowrap="nowrap">用户名</td>
          <td width="127" nowrap="nowrap"><label>
            <input name="username" type="text" id="username" size="20" />
          </label></td>
        </tr>
        <tr>
          <td nowrap="nowrap">密 码</td>
          <td nowrap="nowrap"><input name="password" type="password" id="password" size="20" maxlength="10" /></td>
        </tr>
        <tr><td>验证码</td><td><input id="index_code" name="code" type="text" /></td>
       <td> <img id="imgObj" alt="验证码" src="code.html" />
        <a href="#" onclick="changeImg()">换一张</a></td></tr>
        <tr>
          <td colspan="2" align="center" nowrap="nowrap"><label>
            <input type="submit"  value="注册" />
            <input type="reset"  value="重填" />
          </label></td>
        </tr>
  </table>
</form>

注意标签的src的写法,写成code.html。

其中用于实现“换一张”功能的javascript为下

<script type="text/javascript">
    function changeImg() {
        var imgSrc = $("#imgObj");
        var src = imgSrc.attr("src");
        imgSrc.attr("src", chgUrl(src));
    }
    //时间戳   
    //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳   
    function chgUrl(url) {
        var timestamp = (new Date()).valueOf();
        url = url.substring(0, 17);
        if ((url.indexOf("&") >= 0)) {
            url = url + "×tamp=" + timestamp;
        } else {
            url = url + "?timestamp=" + timestamp;
        }
        return url;
    }
</script>

其中,这一段js用到了jquery,别忘了在head中把jquery的js给引进来。

<script type="text/javascript" src="js/jquery-easyui-1.3.1/jquery-1.8.0.min.js"></script>

到此为止,一个完整的注册程序就完成了。部署,测试,如图

springMVC+Java验证码完善注册功能

注册成功了如下

springMVC+Java验证码完善注册功能

验证码输入错误,如下

springMVC+Java验证码完善注册功能

然后就error了。。springMVC+Java验证码完善注册功能

springMVC+Java验证码完善注册功能

这个注册的功能就基本完善了,当然,其实error的提示应该在原来的注册页面,可以使用ajax来实现,我只是写示例程序,就没那样做了。追求完美的可以自己重构一下Controller的代码,返回json给浏览器,再用ajax实现不刷新页面,就可以实现真正的注册功能了。
最后再啰嗦一句,需要这个demo项目源代码的孩子,请联系邮箱sgl-2014@qq.com

或者去CSDN Code上去下载,地址:https://code.csdn.net/Sgl731524380/verificationcode/tree/master

版权声明:本文为博主原创文章,未经博主允许不得转载。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Irene181 Irene181
2年前
拒绝反爬虫!教你搞定爬虫验证码
导读:目前,许多网站采取各种各样的措施来反爬虫,其中一个措施便是使用验证码。随着技术的发展,验证码的花样越来越多。验证码最初是几个数字组合的简单的图形验证码,后来加入了英文字母和混淆曲线。有的网站还可能看到中文字符的验证码,这使得识别越发困难。使用验证码可以防止应用或者网站被恶意注册、攻击,对于网站、APP而言,大量的无效注册、重复注册甚至是恶意攻击很令
宙哈哈 宙哈哈
1年前
PHP短信验证码防刷方案
短信验证码是通过发送验证码到手机的一种有效的验证码系统。利用短信验证码来注册会员,大大降低了非法注册的数据。
Wesley13 Wesley13
2年前
volley 实现验证码功能
  公司的项目,为防止机器注册,需增加验证码功能,开始以为只是一张图片,通过glide加载个地址就好,但接口的同事说验证码接口是返回一个流,因为服务端不应该做验证码图片的存储,因为验证是不停变动的,但公司的接口都是https,有相应的证书校验环节及头部信息校验,而项目中现存的网络请求是封装的volleyjson请求,只应该返回json的接口,之前了解的
不是海碗 不是海碗
1年前
一文带你看透短信验证码
短信验证码应用于我们生活、工作的方方面面,比如注册登录账号、支付订单、修改密码等等。验证码短信主要出于安全的考虑,防止应用/网站被恶意注册,恶意攻击,对于网站、APP而言,大量的无效注册,重复注册,甚至是恶意攻击很令人头痛。
AWS国庆双重礼,仅限7天
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠AWS精美祥云纪念T恤一件。,仅限7天$20
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
2年前
Python生成图片验证码
最近公司网站,需要在注册模块添加验证码,防止其他人频繁的恶意注册,我们后端使用的是python进行开发,所以研究了下python图片验证码的方法。最后确定使用python里面PIL库,通过Image,ImageDraw,ImageFont,ImageFilter的模块生成图片验证码设计思路(这里就不画图了):(1)用户填写用户名(必须先填)
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
DBShop功能简介
DBShop功能简介商城模块功能功能描述系统设置基本设置1、网站名称、关键字、描述等seo设置2、网站logo、备案号设置3、系统关闭、系统开启、系统时区设置(针对不同国家时区)验证码1、注册验证码2、登录验证码3、商品咨询验证码4、手机验证码消息通知