美文网首页功能专区
Java 收发邮件 (Jakarta Mail)

Java 收发邮件 (Jakarta Mail)

作者: 攻城狮_正 | 来源:发表于2021-03-03 17:39 被阅读0次

    Jakarta Mail API提供了一个独立于平台和协议的框架来构建邮件,完成邮件接收与发送功能。它也包含在Java EE平台中,也可以和Java SE平台一起使用。

    Jakarta Mail的前生是JavaMail。JavaMail最后一个版本是于2018年8月发布,已经停止更新。新项目应该使用Jakarta Mail。

    现在很多邮箱默认关闭smtp,pop3,imap服务,需要在设置中手动开启。

    1257f786fa008bb14fea9aff63591654.png

    如果邮箱是使用授权码,则需要生成授权码(代替下文中密码),这种方式更安全。

    依赖

    注意Jakarta Mail引用的包名与JavaMail不同,我写demo时用的是2.0.0版。

    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>jakarta.mail</artifactId>
        <version>{version}</version>
    </dependency>
    

    所有jar清单:

    e24a18fce617ac7c3e83b7115d60248d.png

    最新版本包含了对Android的支持,可参考Jakarta Mail for Android

    发送邮件

    使用smtp协议接收,本文以QQ邮件上为例。

    • 发送普通文本邮件
    MailObject mailObj = new MailObject();
    mailObj.setFrom("engr-z@qq.com");
    mailObj.setTo(new String[]{"post@engr-z.com"});
    mailObj.setSubject("JavaMail 2.0");
    mailObj.setFormat(MailObject.EmailFormat.TEXT);
    mailObj.setBody("Java 收发邮件 (Jakarta Mail)");
    
    // smtp配置,可保存到properties文件,读取
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.qq.com");
    props.put("mail.smtp.port", 465);
    props.put("mail.smtp.ssl", true);
    // 需要认证
    props.put("mail.smtp.auth", true);
    props.put("mail.smtp.user", "engr-z@qq.com");
    props.put("mail.smtp.pass", "******");
    // 使用ssl
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    //props.put("mail.smtp.socketFactory.fallback", false);
    //props.put("mail.smtp.socketFactory.port", mailConfig.getPort());
    
    // 创建会话
    Session session = Session.getInstance(props, new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            if (Boolean.valueOf(props.getProperty("mail.smtp.auth"))) {
                // 需要认证
                PasswordAuthentication auth = new PasswordAuthentication(props.getProperty("mail.smtp.user"), props.getProperty("mail.smtp.pass"));
                return auth;
            }
            return super.getPasswordAuthentication();
        }
    });
    
    // 构建邮件消息
    MimeMessage msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress(mailObj.getFrom()));
    
    InternetAddress[] address = new InternetAddress[mailObj.getTo().length];
    for (int i = 0, j = mailObj.getTo().length; i < j; i++) {
        address[i] = new InternetAddress(mailObj.getTo()[i]);
    }
    // 可以用msg.setRecipients方法增加多个接收人,指定接收人类型
    // Message.RecipientType.CC 抄送
    // Message.RecipientType.BCC 密送
    msg.setRecipients(Message.RecipientType.TO, address);
    
    msg.setSubject(mailObj.getSubject());
    if (MailObject.EmailFormat.HTML.equals(mailObj.getFormat())) {
        // html格式
        msg.setContent(mailObj.getBody(), "text/html;charset=utf-8");
    } else {
        msg.setText(mailObj.getBody());
    }
    msg.setSentDate(new Date());
    
    // 发送邮件
    Transport.send(msg);
    
    • 发送带附件的邮件
    MailObject mailObj = new MailObject();
    mailObj.setFrom("engr-z@qq.com");
    mailObj.setTo(new String[]{"post@engr-z.com"});
    mailObj.setSubject("JavaMail 2.0");
    mailObj.setFormat(MailObject.EmailFormat.TEXT);
    mailObj.setBody("Java 收发邮件 (Jakarta Mail)");
    
    // smtp配置,可保存到properties文件,读取
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.qq.com");
    props.put("mail.smtp.port", 465);
    props.put("mail.smtp.ssl", true);
    // 需要认证
    props.put("mail.smtp.auth", true);
    props.put("mail.smtp.user", "engr-z@qq.com");
    props.put("mail.smtp.pass", "******");
    // 使用ssl
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    //props.put("mail.smtp.socketFactory.fallback", false);
    //props.put("mail.smtp.socketFactory.port", mailConfig.getPort());
    
    // 创建会话
    Session session = Session.getInstance(props, new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            if (Boolean.valueOf(props.getProperty("mail.smtp.auth"))) {
                // 需要认证
                PasswordAuthentication auth = new PasswordAuthentication(props.getProperty("mail.smtp.user"), props.getProperty("mail.smtp.pass"));
                return auth;
            }
            return super.getPasswordAuthentication();
        }
    });
    
    // 构建邮件消息
    MimeMessage msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress(mailObj.getFrom()));
    
    InternetAddress[] address = new InternetAddress[mailObj.getTo().length];
    for (int i = 0, j = mailObj.getTo().length; i < j; i++) {
        address[i] = new InternetAddress(mailObj.getTo()[i]);
    }
    // 可以用msg.setRecipients方法增加多个接收人,指定接收人类型
    // Message.RecipientType.CC 抄送
    // Message.RecipientType.BCC 密送
    msg.setRecipients(Message.RecipientType.TO, address);
    
    msg.setSubject(mailObj.getSubject());
    
    Multipart mp = new MimeMultipart();
    
    // 邮件内容
    MimeBodyPart body = new MimeBodyPart();
    if (MailObject.EmailFormat.HTML.equals(mailObj.getFormat())) {
        // html格式
        body.setContent(mailObj.getBody(), "text/html;charset=utf-8");
    } else {
        body.setText(mailObj.getBody());
    }
    mp.addBodyPart(body);
    
    // 附件
    for (File file : mailObj.getFiles()) {
        MimeBodyPart attachment = new MimeBodyPart();
        attachment.attachFile(file);
        mp.addBodyPart(attachment);
    }
    
    msg.setContent(mp);
    msg.setSentDate(new Date());
    
    // 发送邮件
    Transport.send(msg);
    

    代码中MailObj是我创建的MailObject对象,MailObject封装了邮件相关的信息:

    /**
     * @author Engr-Z
     * @since 2021/3/3
     */
    @Data
    public class MailObject {
    
        enum EmailFormat {
            TEXT, HTML
        }
    
        /**
         * 发件人
         */
        private String from;
    
        /**
         * 收件人
         */
        private String[] to;
    
        /**
         * 抄送人
         */
        private String[] cc;
    
        /**
         * 密送人
         */
        private String[] bcc;
    
        /**
         * 邮件标题
         */
        private String subject;
    
        /**
         * 邮件内容
         */
        private String body;
    
        /**
         * 邮件格式
         */
        private EmailFormat format;
    
        /**
         * 附件
         */
        private File[] files;
    
    }
    

    接收邮件

    接收邮件常用的协议有pop3,imap和exchange。exchange是微软的邮箱协议,Jakarta Mail暂不支持。

    • 使用pop3协议
    // pop3配置,可保存到properties文件,读取
    Properties props = new Properties();
    props.put("mail.pop3.host", "pop.qq.com");
    props.put("mail.pop3.port", 995);
    props.put("mail.pop3.ssl", true);
    // 需要认证
    props.put("mail.pop3.auth", true);
    props.put("mail.pop3.user", "post@engr-z.com");
    props.put("mail.pop3.pass", "******");
    // 使用ssl
    props.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    //props.put("mail.pop3.socketFactory.fallback", false);
    //props.put("mail.pop3.socketFactory.port", mailConfig.getPort());
    
    Session session = Session.getDefaultInstance(props);
    Store store = session.getStore(mailConfig.getProtocol().value);
    if (Boolean.valueOf(props.getProperty("mail.pop3.auth"))) {
        // 需要认证
        store.connect(mailConfig.getHost(), mailConfig.getPort(), props.getProperty("mail.pop3.user"), props.getProperty("mail.pop3.pass"));
    } else {
        store.connect();
    }
    
    // 获取收件箱 store.getDefaultForlder
    Folder mbox = store.getFolder("INBOX");
    // INBOX
    mbox.open(Folder.READ_ONLY);
    System.out.println(mbox.getName());
    int msgCount = mbox.getMessageCount();
    System.out.println("邮件总数:" + msgCount);
    // 取最新的邮件
    Message msg = mbox.getMessage(msgCount);
    System.out.println("邮件主题:" + msg.getSubject());
    System.out.println("发件人:" + msg.getFrom());
    // 返回数组
    System.out.println("收件人:" + msg.getRecipients(Message.RecipientType.TO));
    // 没有为null
    System.out.println("抄送人:" + msg.getRecipients(Message.RecipientType.CC));
    // 没有为null
    System.out.println("密送人:" + msg.getRecipients(Message.RecipientType.BCC));
    // MimeMultipart 对像
    System.out.println("邮件内容:" + msg.getContent());
    
    • 使用imap协议

    只需把上面props配置key改为imap即可,QQ邮件imap端口是 993:

    // imap配置,可保存到properties文件,读取
    Properties props = new Properties();
    props.put("mail.imap.host", "imap.qq.com");
    props.put("mail.imap.port", 993);
    props.put("mail.imap.ssl", true);
    // 需要认证
    props.put("mail.imap.auth", true);
    props.put("mail.imap.user", "post@engr-z.com");
    props.put("mail.imap.pass", "******");
    // 使用ssl
    props.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    //props.put("mail.imap.socketFactory.fallback", false);
    //props.put("mail.imap.socketFactory.port", mailConfig.getPort());
    
    Session session = Session.getDefaultInstance(props);
    Store store = session.getStore(mailConfig.getProtocol().value);
    if (Boolean.valueOf(props.getProperty("mail.imap.auth"))) {
        // 需要认证
        store.connect(mailConfig.getHost(), mailConfig.getPort(), props.getProperty("mail.imap.user"), props.getProperty("mail.imap.pass"));
    } else {
        store.connect();
    }
    
    // 以下操作与pop3相同......
    

    开发中我们还可以使用Apache Commons Email收发邮件,它的API使用起来更简单。Spring Boot也有邮件模块。有兴趣可以到官网了解。

    Jakrata项目地址:eclipse-ee4j.github.io/mail/


    除非注明,否则均为"攻城狮·正"原创文章,转载请注明出处。
    本文链接:https://engr-z.com/298.html

    相关文章

      网友评论

        本文标题:Java 收发邮件 (Jakarta Mail)

        本文链接:https://www.haomeiwen.com/subject/rcqcqltx.html