文章目录

  • 一、GUI开发
  • 二、读取邮件、验证验证码
  • 三、发邮件



本文主要学习的是邮箱验证码知识,只是需要一个载体来验证这个功能,所以选择了gui。


直接看最终效果图


java怎么验证邮箱的有效性_mail


java怎么验证邮箱的有效性_邮箱验证码_02

两个输入框两个按钮,输入邮箱,点击获取,登入邮箱查看验证码,再输入验证码,点击登录,流程结束

一、GUI开发

定义一个JFrame

JFrame frame = new JFrame("登录");
// 设置frame的其他属性
frame.setSize(300, 300);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
// 替换左上角默认java图标,如果图片不存在,还会使用默认图标
Image icon = Toolkit.getDefaultToolkit().getImage("C:\\Users\\diyan\\Pictures\\avatar.jpg");
frame.setIconImage(icon);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

定义面板JPanel上的控件,绝对定位布局,通过坐标(x,y)和宽高(w,h)来实现控件的布局,这里的数字需要进行简单的计算方能保证控件的对齐

// 第一行
JLabel title = new JLabel("登录界面");
title.setBounds(100, 20, 300, 30);
// 第二行
JLabel mailLabel = new JLabel("邮箱:");
mailLabel.setBounds(30, 70, 100, 30);
JTextField mailField = new JTextField(17);
mailField.setBounds(80, 70, 170, 30);
// 第三行
JLabel codeLabel = new JLabel("验证码:");
codeLabel.setBounds(30, 120, 100, 30);
JTextField codeField = new JTextField(12);
codeField.setBounds(80, 120, 100, 30);
JButton getBtn = new JButton("获取");
getBtn.setBounds(185, 120, 65, 30);
// 第四行
JButton loginBtn = new JButton("登录");
loginBtn.setBounds(30, 170, 220, 30);

定义一个JPanel,把上一步的控件全部add进来

JPanel panel = new JPanel();
panel.setLayout(null);

panel.add(title);
panel.add(mailLabel);
panel.add(mailField);
panel.add(codeLabel);
panel.add(codeField);
panel.add(getBtn);
panel.add(loginBtn);

面板里有两个按钮,点击事件处理,具体的处理逻辑就是本文的核心

java怎么验证邮箱的有效性_java怎么验证邮箱的有效性_03

getBtn.addActionListener(e -> {
    String mail = mailField.getText();
    if (mail == null || mail.isEmpty()) {
        JOptionPane.showMessageDialog(frame, "邮箱不能为空!");
        return;
    }
    if (!isValidEmail(mail)) {
        JOptionPane.showMessageDialog(frame, "邮箱格式不合法!");
        return;
    }
    // 获取验证码前先判断当前邮箱5分钟之内是否已发送过验证码
    JDialog dialog = showProgress(frame);
    // 此处的111111为随便填的6个数字,为的就是返回code300,当然该代码还可优化
    Map<String, Object> res = MailUtil.verifyCode(mail, "111111");
    if ((int) res.get("code") == 301) {
        MailUtil.sendEmail(mail);
        hideProgress(dialog);
        JOptionPane.showMessageDialog(frame, "验证码已发送!");
    } else if ((int) res.get("code") == 300) {
        hideProgress(dialog);
        JOptionPane.showMessageDialog(frame, "您的验证码获取过于频繁,请稍后再试!");
    }

});

loginBtn.addActionListener(e -> {
    System.out.println("点击了登录");
    String mail = mailField.getText();
    String code = codeField.getText();
    if (mail == null || mail.isEmpty()) {
        JOptionPane.showMessageDialog(frame, "邮箱不能为空!");
        return;
    }
    if (!isValidEmail(mail)) {
        JOptionPane.showMessageDialog(frame, "邮箱格式不合法!");
        return;
    }
    if (code == null || code.isEmpty()) {
        JOptionPane.showMessageDialog(frame, "验证码不能为空!");
        return;
    }
    JDialog dialog = showProgress(frame);
    Map<String, Object> res = MailUtil.verifyCode(mail, code);
    if ((int) res.get("code") == 200) {
        hideProgress(dialog);
        JOptionPane.showMessageDialog(frame, "登录成功!");
    } else {
        hideProgress(dialog);
        JOptionPane.showMessageDialog(frame, "登录失败," + (String) res.get("msg"));
    }

});

最后把面板JPanel添加到JFrame中,并让JFrame显示

frame.add(panel);
// 显示frame
frame.setVisible(true);

工具方法

java怎么验证邮箱的有效性_gui_04

显隐等待框

// 显示等待框
private static JDialog showProgress(JFrame frame) {
    JDialog dialog = new JDialog(frame, "登陆中...");
    dialog.setSize(100, 100);
    dialog.setLocationRelativeTo(null);
    dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
    dialog.setVisible(true); // 显示进度等待框
    return dialog;
}

// 隐藏等待框
private static void hideProgress(JDialog dialog) {
    dialog.setVisible(false); // 关闭进度等待框
    dialog.dispose(); // 释放资源
}

java怎么验证邮箱的有效性_gui_05


邮箱格式验证

private static final Pattern EMAIL_PATTERN =
Pattern.compile(
    "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
    "\\@" +
    "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
    "(" +
    "\\." +
    "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
    ")+"
);


private static boolean isValidEmail(String email) {
    return EMAIL_PATTERN.matcher(email).matches();
}

二、读取邮件、验证验证码

关于邮件读写,我这里使用的是qq邮箱

java怎么验证邮箱的有效性_java怎么验证邮箱的有效性_06

读取邮件

/**
 * 读取发件箱指定收件人邮件
 */
public static Map<String,Object> readMail(String host, int port, String userName, String password, String toAddress,String code) throws MessagingException, IOException {
    Map<String,Object> res = new HashMap<>();
    res.put("code",301);
    res.put("msg","验证失败");

    Properties properties = new Properties();
    properties.put("mail.store.protocol", "imaps");
    // 普通邮箱
    properties.put("mail.imaps.starttls.enable", "true");
    properties.put("mail.imaps.host", host);
    properties.put("mail.imaps.port", port);

    Session session = Session.getDefaultInstance(properties);
    Store store = session.getStore();
    store.connect(userName, password);
    Folder box = store.getFolder("已发送");
    box.open(Folder.READ_ONLY);
    // 应该只能取最近一个月或一年的
    Message[] messages = box.getMessages();
    for (Message msg : messages) {
        if (msg instanceof MimeMessage) {
            MimeMessage mimeMessage = (MimeMessage) msg;

            // 获取收件人
            StringBuilder addressSb = new StringBuilder();
            InternetAddress[] recipients = (InternetAddress[]) mimeMessage.getAllRecipients();
            for (InternetAddress addr : recipients) {
                addressSb.append(addr.getAddress()).append(",");
            }
            String address = addressSb.substring(0, addressSb.length() - 1);
            if(!address.contains(toAddress)){
                System.out.println("不是目标用户,PASS");
                continue;
            }

            // 获取发送时间,计算有效期
            Date sentDate = mimeMessage.getSentDate();
            Date now = new Date();
            long fiveMinute = 5 * 60 * 1000;
            boolean flag = fiveMinute >= (now.getTime() - sentDate.getTime());
            if (!flag) {
                System.out.println("验证码已失效,PASS");
                continue;
            }

            // 获取邮件内容
            Object content = mimeMessage.getContent();
            if (content instanceof String) {
                // 正则表达式匹配出验证码
                String expression = "\\d+";
                Pattern pattern = Pattern.compile(expression);
                Matcher matcher = pattern.matcher((String) content);
                if (matcher.find()) {
                    String realCode = matcher.group();
                    if(realCode.equals(code)){
                        res.put("code",200);
                        res.put("msg","验证成功");
                    }else{
                        res.put("code",300);
                        res.put("msg","验证码错误");
                    }
                    System.out.println("验证码==>" + realCode);
                }
            }
        }
    }
    box.close();
    store.close();
    return res;
}

验证码

public static Map<String,Object> verifyCode(String mail,String code){
    Map<String,Object> res = new HashMap<>();

    try {
        res = MailUtil.readMail("imap.qq.com", 993, "真实邮箱账号", "真实邮箱密码"
                                , mail,code);
    }catch (Exception e){
        res.put("code",302);
        res.put("msg","验证异常:" + e.getMessage());
        e.printStackTrace();
    }
    return res;
}

三、发邮件

public static void sendEmail(String host, int port, String userName, String password,
                             String toAddress, String subject, String message) throws MessagingException, IOException {
    Properties properties = new Properties();
    //  是否需要用户认证
    properties.put("mail.smtp.auth", "true");
    // 普通邮箱
    properties.put("mail.smtp.starttls.enable", "true");
    properties.put("mail.smtp.host", host);
    properties.put("mail.smtp.port", port);
    // qq邮箱
    properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");

    Session session = Session.getInstance(properties, new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(userName, password);
        }
    });
    session.setDebug(true);

    MimeMessage mimeMessage = new MimeMessage(session);
    // qq邮箱
    mimeMessage.setFrom(new InternetAddress("真实发件人邮箱地址"));
    mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
    mimeMessage.setSubject(subject);
    mimeMessage.setText(message);

    Transport.send(mimeMessage);
}

发邮件方法简化

public static void sendEmail(String toAddress){
try {
    MailUtil.sendEmail("smtp.qq.com", 465, "真实邮箱地址", "真实邮箱密码"
    , toAddress, "测试验证码", "【苏州测试】您的验证码为" + MailUtil.generateRandomCode() + ",有效期为5分钟");
}catch (Exception e){
    e.printStackTrace();
}

}

生成4位随机验证码

public static String generateRandomCode() {
    Random random = new Random();
    StringBuilder code = new StringBuilder();
    for (int i = 0; i < 4; i++) {
        int num = random.nextInt(10);
        code.append(num);
    }
    return code.toString();
}