简介
作者简介:青铜码农,和大多数同学一样从零开始一步步学习,一步步积累。期待您的关注,让我们一起成长~注:本人学疏才浅,文章如有错误之处,敬请指正~
内容简介:为了保证登陆的安全性,通常会要求在登陆界面中输入验证码。本内容主要讲解如何使用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