首页 > 编程语言 >JavaWeb登录实现验证码功能

JavaWeb登录实现验证码功能

时间:2024-08-14 13:54:05浏览次数:15  
标签:String 登录 nextInt int 验证码 CAPTCHA import g2 JavaWeb

1、新建两个工具类

import java.util.Arrays;

public class CreateVerificationCode {
    /**
     * 验证码难度级别
     */
    public enum SecurityCodeLevel {
        Simple,
        Medium,
        Hard
    }

    public static String getSecurityCode() {
        return (String) getSecurityCode(4, SecurityCodeLevel.Medium, false);
    }

    public static String getSecurityCode(int length, SecurityCodeLevel level, boolean isCanRepeat) {
        int len = length;
        //除去容易混淆的0和o,1和l
        char[] codes = {
                '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                'j', 'm', 'n', 'p', 'q', 'r', 's', 't','u',
                'v', 'w', 'x', 'y', 'z','A','B','C','D','E',
                'F','G','H','J','K','L','M','N','P','Q','R','S',
                'T','U','V','W','X','Y','Z'};
        if(level==SecurityCodeLevel.Simple){
            codes= Arrays.copyOfRange(codes,0,9);
        }else if (level==SecurityCodeLevel.Medium){
            codes= Arrays.copyOfRange(codes,0,33);
        }
        int n=codes.length;
        //抛出运行时异常
        if (len>n&&isCanRepeat==false){
            throw new RuntimeException(
                    String.format("调用securitycode.getSecurityCode(%1$s,len,level,isCanRepeat,n)"));}
        char[] result=new char[len];
        //判断能否出现重复的字符
        if (isCanRepeat){
            for(int i=0;i<result.length;i++){
                //索引0 and n-1
                int r=(int)(Math.random()*n);
                //将result中的第i个元素设为codes[r]存放的数值
                result[i]=codes[r];
            }
        }else {
            for (int i=0;i<result.length;i++){
                int r=(int)(Math.random()*n);
                //将result中的第i个元素设为codes[r]存放的数值
                result[i]=codes[r];
                codes[r]=codes[n-1];
                n--;
            }
        }
        return String.valueOf(result);
    }
}

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 可生成数字,大写,小写字母及三者混合类型的验证码,支持自定义干扰线,图文颜色
 */
public class CreateVerificationCodeImage {
    private String securityCode;
    public CreateVerificationCodeImage(String securityCode){
        this.securityCode=securityCode;
    }
    //高度
    private static final int CAPTCHA_HEIGHT = 35;
    //宽度
    private static final int CAPTCHA_WIDTH  = 100;
    //数字的长度
    //private static final int NUMBER_CNT     = 6;
    private Random r = new Random();
    //  字体
    private String[] fontNames = { "宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312" };
    //private String[] fontNames = { "宋体",  "黑体", "微软雅黑"};

    /**
     * 机能概要:生成随机的颜色
     * @return
     */
    private Color randomColor() {
        int red = r.nextInt(150);
        int green = r.nextInt(150);
        int blue = r.nextInt(150);
        return new Color(red, green, blue);
    }

    /**
     * 机能概要:生成随机的字体
     * @return
     */
    private  Font randomFont() {
        int index = r.nextInt(fontNames.length);
        String fontName = fontNames[index];// 生成随机的字体名称
        int style = r.nextInt(4);// 生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
        int size = r.nextInt(5) + 24; // 生成随机字号, 24 ~ 28
        // int size = r.nextInt(5) + 15; // 生成随机字号, 20 ~ 24
        return new Font(fontName, style, size);
    }

    // 画干扰线
    private  void drawLine(BufferedImage image) {
        int num = 5;// 一共画5条
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        for (int i = 0; i < num; i++) {// 生成两个点的坐标,即4个值
            int x1 = r.nextInt(CAPTCHA_WIDTH);
            int y1 = r.nextInt(CAPTCHA_HEIGHT);
            int x2 = r.nextInt(CAPTCHA_WIDTH);
            int y2 = r.nextInt(CAPTCHA_HEIGHT);
            g2.setStroke(new BasicStroke(1.5F));
            g2.setColor(randomColor()); // 随机生成干扰线颜色
            g2.drawLine(x1, y1, x2, y2);// 画线
        }
    }
    // 创建BufferedImage,生成图片
    public BufferedImage createImage() {
        BufferedImage image = new BufferedImage(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        // 背景色,白色
        g2.setColor(new Color(255, 255, 255));
        g2.fillRect(0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT);

        // 向图片中画4个字符  String securityCode
        for (int i = 0; i < securityCode.length(); i++) {// 循环四次,每次生成一个字符
            String s = securityCode.charAt(i) + "";// 随机生成一个字母
            // float x = i * 1.0F * CAPTCHA_WIDTH / NUMBER_CNT; // 设置当前字符的x轴坐标
            float x = i * 1.0F * CAPTCHA_WIDTH / 4+7F; // 设置当前字符的x轴坐标
            g2.setFont(randomFont()); // 设置随机字体
            g2.setColor(randomColor()); // 设置随机颜色
            g2.drawString(s, x, CAPTCHA_HEIGHT-7); // 画图,依次将字符写入到图片的相应位置-------------------
        }
        drawLine(image); // 添加干扰线
        return image;
    }
}

2、前端显示验证码及js变换验证码

<input name="vericode" placeholder="验证码"  style="height: 35px" >
                    <img style="position: relative;top: 11px;" id="vericodeImg" src="imageCode" class="captcha-image" onclick="changeImg()">



<script>
function changeImg() {
        //需要让每次请求的url都发生变化。否则服务器会认为访问的时一张图片,就不会刷新请求了
        //每次url一样,服务器会认为访问的url是同一张图片,没变化啊
        $("#vericodeImg").attr("src","imageCode?"+Math.random())
    }
</script>

3、servlet设置返回内容及清楚缓存

import com.xszx.util.CreateVerificationCode;
import com.xszx.util.CreateVerificationCodeImage;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/imageCode")
public class ImageCodeServelt extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String vericode= CreateVerificationCode.getSecurityCode();
        HttpSession session=req.getSession();
        session.setAttribute("verityCode",vericode);
        //设置返回的内容
        resp.setContentType("img/jpeg");
        //浏览器不缓存响应内容--验证码图片,点一次就要刷新一次,所以不能有缓存出现
        resp.setHeader("Pragma","No-cache");
        resp.setHeader("Cache-Control","no-cache");
        //设置验证码失效时间
        resp.setDateHeader("Expires",0);
        //以字节流发过去,交给img的src属性去解析即可
        ImageIO.write(new CreateVerificationCodeImage(vericode).createImage(),"JPEG",resp.getOutputStream());
    }
}

4、登录servlet判断前端返回值

 String vericode=req.getParameter("vericode");
 String generatedCode= (String) req.getSession().getAttribute("verityCode");

5、实现效果

标签:String,登录,nextInt,int,验证码,CAPTCHA,import,g2,JavaWeb
From: https://blog.csdn.net/weixin_68489989/article/details/141166425

相关文章

  • 宝塔硬盘满了,宝塔不能登录,数据库宕机解决办法
    1.命令查看硬盘是否满了:df如果满了,清楚日志,清理磁盘打开SSH软件清理二进制日志:rm-f/www/server/data/ib_*rm-f/www/server/data/mysql-bin*启动数据库servicemysqldstart2.宝塔就可以连接上了,查看一下占满的原因:3)数据库日志占满,关闭日志就行了,需要打开的话重新打开4)......
  • 个人中心增加上次登录时间和注册时间
    文件:user\profile\template\profile.htm<divclass="form-group"><labelclass="control-label">{langusername}</label><divclass="controls-container"><pclass="form-control......
  • 京东旋转验证码识别代码
    京东旋转验证码样例如下:现在京东更新了很多新图片,我们再次进行了大量数据标记,完成了这款验证码的更新。现在正确率可以达到95%左右。下边是这款验证码的识别代码:importbase64importrequestsimportdatetimeimportnumpyasnpfromioimportBytesIOfromPILimpo......
  • mysql: auth_socket登录
    一,默认安装的mysql用户root是auth_socket方式登录root@localhost的authentication_string为空,   它的plugin为auth_socket二,如何登录?1,从命令行正常登录会报错:liuhongdi@lhdpc:/data/site/gsapi$mysql-uroot-hlocalhost-pEnterpassword:ERROR1698(28000):......
  • 如何在 Flask 中实现用户登录
    在Flask中实现用户登录功能通常涉及以下几个步骤:设置Flask应用、创建用户模型、处理用户注册、实现登录逻辑以及保护受限路由。下面就是我总结得一些经验,可以一起聊一聊。1、问题背景在使用Flask框架构建Web应用程序时,通常需要实现用户登录功能。常见的需求是将......
  • 连接被拒绝,因为没有授权此用户账户进行远程登录
    解决远程连接被拒绝的问题,需要进行以下操作1234:按下Windows+R组合键,输入“sysdm.cpl”,打开系统属性窗口。在系统属性窗口中,选择“远程”选项卡,点击“选择用户”按钮。点击“添加”,再点击“高级”,选择“立即查找”,将所需用户添加到列表中。检查云服务器远程桌面权限配置,打开......
  • springboot 整合微信公众号--验证码推送(spring boot+测试号)
    一、公众号开发初探这里会使用到自己的域名进行交互,没有域名的小伙伴可以使用  内网穿透(NATAPP), 如果没有使用过的的同学请移步 20秒轻松上手NATAAPP(内网穿透)公众号整体流程:用户扫公众号二维码。然后发一条消息:验证码。我们通过api回复一个随机的验证码,并且存入re......
  • 域用户登入提示:无法登录到你的账户,通常可以通过账户注销。。。
    问题用户账号登录提示:无法登入到你的账户通常可以通过从你的账户注销,然后重新登录来解决此问题。如果不立即注销,你创建的任何文件或进行的任何更改都将会丢失。我们有时账户出现问题时,在我们的域内电脑的Users文件夹中会出现一个temp账户,这个账户只是临时账户,我们不论存储任何......
  • 【验证码逆向专栏】某东 M 端登录滑块逆向分析
    声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作......
  • 【算家云】基础操作教程01 注册与登录
    为方便广大用户快速上手算家云,我们将提供算家云的基础操作教程,即便是零基础的小白也能轻松使用。现在就跟着一起来吧!一、进入官网在浏览器地址栏输入以下网址,进入算家云官网【https://www.suanjiayun.com/】点击【立即体验】或右上角【进入平台】,打开注册页面二、注册......