Java案例——实现验证码登陆

简介

作者简介:青铜码农,和大多数同学一样从零开始一步步学习,一步步积累。期待您的关注,让我们一起成长~注:本人学疏才浅,文章如有错误之处,敬请指正~

内容简介:为了保证登陆的安全性,通常会要求在登陆界面中输入验证码。本内容主要讲解如何使用Java语言实现验证码登陆功能。

获取完整源码及图片素材:

链接:https://pan.baidu.com/s/17USG0Kxm1uvxAXy7yP7sPw 
提取码:pncz

功能预览:

Java实现验证码功能

为了方便,此处只当用户名为123456,且密码为123456时就登陆成功。
    由功能预览可知:当输入的用户名、密码都正确时将提示登陆成功;没有输入用户名将提示用户名为空,密码、验证码也是如此;且当输入的用户名或者密码有误时,会提示用户名或密码错误,且当错误达到三次时,登陆按钮将被禁用,登陆按钮显示XX秒后重试;每次登陆成功或信息有误时,验证码都会更新一次;验证码不区分大小写。点击重置按钮,所有信息将被清空,验证码会刷新;点看不清按钮,将更换验证码。

1.创建窗体类
   创建一个类继承于JFrame,在实现方法中添加组件和按钮监听事件,在main方法中实例化类并设置窗体可见。代码如下:

public class yanzhengma extends JFrame {
    private JTextField nameText;// 用户名输入框
    private JPasswordField pwdText;// 密码输入框
    private JTextField codeText;// 验证码输入框
    private JButton button_1;// 登陆按钮
​
    public yanzhengma() {
        super();
        setResizable(false);
        setTitle("Java实现验证码功能");
        setBounds(700, 450, 400, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
​
        JPanel panel = new JPanel();
        panel.setLayout(null);
        getContentPane().add(panel, BorderLayout.CENTER);
​
        JLabel label_1 = new JLabel();
        label_1.setText("用户名:");
        label_1.setBounds(10, 10, 50, 20);
        panel.add(label_1);
​
        nameText = new JTextField();
        nameText.setBounds(60, 10, 300, 20);
        panel.add(nameText);
​
        JLabel label_2 = new JLabel();
        label_2.setText("密 码:");
        label_2.setBounds(10, 35, 50, 20);
        panel.add(label_2);
​
        pwdText = new JPasswordField();
        pwdText.setBounds(60, 35, 300, 20);
        panel.add(pwdText);
​
        JLabel label_3 = new JLabel();
        label_3.setText("验证码:");
        label_3.setBounds(10, 75, 50, 20);
        panel.add(label_3);
​
        codeText = new JTextField();
        codeText.setBounds(60, 70, 80, 30);
        panel.add(codeText);
​
        button_1 = new JButton("登陆");
        button_1.setBounds(30, 110, 80, 20);
        panel.add(button_1);
        button_1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String username = nameText.getText();// 从文本框中获取用户名
                String password = new String(pwdText.getPassword());// 从密码框中获取密码
                String code = codeText.getText().toUpperCase();// 获得输入的验证码,并转换为大写字母
                String info = "";// 提示信息
                // 判断用户名是否为null或空的字符串
                if (username == null || username.isEmpty()) {
                    info = "用户名为空!";
                }
                // 判断密码是否为null或空的字符串
                else if (password == null || password.isEmpty()) {
                    info = "密码为空!";
                }
                // 判断验证码是否为null或空的字符串
                else if (code == null || code.isEmpty()) {
                    info = "验证码为空!";
                }
                // 如果用户名与密码均为"123456",则登录成功
                else if (username.equals("123456") && password.equals("123456")) {
                    info = "登录成功!";
                } else {
                    info = "用户名或密码错误!";
                }
                JOptionPane.showMessageDialog(null, info);// 通过对话框弹出用户登录信息
            }
        });
​
        JButton button_2 = new JButton("重置");
        button_2.setBounds(130, 110, 80, 20);
        panel.add(button_2);
        button_2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                nameText.setText("");// 清空用户名文本框
                pwdText.setText("");// 清空密码框
                codeText.setText("");// 清空验证码框
            }
        });
​
        JButton button_3 = new JButton("看不清");
        button_3.setBounds(230, 110, 80, 20);
        panel.add(button_3);
        button_3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            //待补充的代码
            }
        });
    }
​
    public static void main(String[] args) {
        yanzhengma frame = new yanzhengma();
        frame.setVisible(true);// 窗体
    }
}

运行效果如图:

2.创建验证码面板类

在此类中规定作为随机验证码的26个字母;在面板中绘制出随机输出的验证码字母;验证码需要随机调整角度,大小。代码如下:

class CodePanel extends JPanel {
    Random random = new Random();// 随机数实例化
    private String code = "";// 验证码
​
    public CodePanel() {
        this.setVisible(true);
        setLayout(null);
    }
​
    public void paint(Graphics g) {
        String wenzi = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";// 验证码的字母
        BufferedImage image = new BufferedImage(120, 35, BufferedImage.TYPE_INT_BGR);
        Graphics graphics = image.getGraphics();
        if (!code.isEmpty()) {
            code = "";
        }
        graphics.setFont(new Font("楷体", Font.BOLD, 20));
        graphics.fillRect(0, 0, 120, 35);
​
        for (int i = 0; i < 4; i++) {//生成四个待验证的文字
            int index = random.nextInt(wenzi.length());
            String s = wenzi.substring(index, index + 1);// 截取字段
            code += s;// 验证码新增截取字段
            graphics.setColor(Color.green);
            Graphics2D g2d = (Graphics2D) graphics;
            AffineTransform transform = new AffineTransform();
            transform.rotate(random.nextInt(45) * 3.14 / 180, 22 * i + 8, 7);// 随机转动
            float scaleSize = random.nextFloat() + 0.8f;// 缩放文字
            if (scaleSize > 1f)
                scaleSize = 1f;// 如果scaleSize大于1,则等于1
            transform.scale(scaleSize, scaleSize); // 进行缩放
            g2d.setTransform(transform);// 设置AffineTransform对象
            graphics.drawString(s, 120 / 6 * i + 28, 35 / 2);// 画出验证码
        }
        g.drawImage(image, 0, 0, null);
    }
​
    public void draw() {
        repaint();// 重新绘制验证码
    }
​
    public String getNum() {
        return code;// 返回验证码
    }
}

并在yanzhengma类中补充一下新代码:

public class yanzhengma extends JFrame {
// 用户名输入框
// 密码输入框
// 验证码输入框
// 登陆按钮
    private CodePanel codePanel = null;
    private int num = 0;// 计数器
​
    public yanzhengma() {
        //此处省略不作改变代码
        codePanel = new CodePanel();
        codePanel.setBounds(150, 67, 100, 35);
        getContentPane().add(codePanel);
​
        //此处省略不作改变代码
                // 如果用户名与密码均为"123456",则登录成功
                else if (username.equals("123456") && password.equals("123456")) {
                    info = "登录成功!";
                    codePanel.draw();// 更新验证码
                } else {
                    info = "用户名或密码错误!";
                    num++;
                    if (num == 3) {
                        button_1.setEnabled(false);
                        // 设置计时任务 1s 循环5次 停止任务
                        Timer timer = new Timer();
                        timer.schedule(new TimerTask() {
                            int i = 5;
​
                            @Override
                            public void run() {
                                i--;
                                button_1.setText(i + "秒");
                                if (i <= 0) {
                                    button_1.setEnabled(true);// 设置按钮可点击 并且停止任务
                                    button_1.setText("登陆");
                                    codePanel.draw();// 更新验证码
                                    timer.cancel();
                                }
                            }
                        }, 0, 1000);
                    }
                }
                JOptionPane.showMessageDialog(null, info);// 通过对话框弹出用户登录信息
            }
        });
​
        //此处省略不作改变代码
​
        JButton button_3 = new JButton("看不清");
        button_3.setBounds(230, 110, 80, 20);
        panel.add(button_3);
        button_3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (codePanel != null) {
                    codePanel.draw();// 更新验证码
                }
            }
        });
    }
​
    public static void main(String[] args) {
        //此处省略不作改变代码
    }
}

至此,该功能已实现完毕,效果如上视频所示。类似的,可以将26个字母换成指定文字。也可以实现运算功能的验证码。

如果想验证码框带图片,可在CodePanel类中的paint()方法添加一下代码:

    public void paint(Graphics g) {
        //此处省略不作改变代码
​
        Image bgImage=null;
        try {
            bgImage= ImageIO.read(new File("src/image.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
​
        image.getGraphics().drawImage(bgImage,0,0,120,35,null);
​
        for (int i = 0; i < 4; i++) {//生成四个待验证的文字
        //此处省略不作改变代码
    }

运行效果如图:

或者可以在验证码字母中添加干扰线,在CodePanel类中的paint()方法添加一下代码:

        int x1 = random.nextInt(20);// 第一条线起始X坐标
        int x2 = random.nextInt(30) + 35;// 第二条线起始X坐标,第一条线的终止X坐标
        int x3 = random.nextInt(30) + 90;// 第二条线的终止X坐标
        int y1 = random.nextInt(20);// 第一条线的Y坐标
        int y2 = random.nextInt(10) + 20;// 第二条线起始Y坐标,第一条线的终止Y坐标
        int y3 = random.nextInt(10) + 5;// 第二条线的终止Y坐标
        graphics.setColor(Color.black);
        graphics.drawLine(x1, y1, x2, y2);
        graphics.drawLine(x2, y2, x3, y3);

运行效果如图:

还可以实现一个动态滑块验证码,滑块验证码比前几种都要难、复杂。后期将会出一期滑块验证码的讲解,敬请关注!

图片

我是码龙,如果我的文章对您有帮助,请点个 👍🏻 支持我一下,谢谢~

​微信公众号:CodeDragons

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Waylon1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值