Java发送电子邮件

导入依赖/jar包

通过maven导入javax.mail和javax.activation的依赖,或者去Maven Repository 下载这两个包(注意包名),这两个包已经完善了,不会再有新版本,可以直接复制粘贴。

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

申请邮件服务器方的POP3/SMTP授权码

这里以QQ邮箱为例,其他的也差不多。

设置->账户->往下拉->开启POP3/SMTP服务。

在这里插入图片描述


发送一封简单邮件

发送一封不带附件的邮件

发件人是固定的,不需要传参哦,如果改变发件人,就要改授权码对应改发件人的授权码

/**
* 发送仅包含html文本的邮件
*
* @param to 收件人
* @param subject 邮件主题
* @param msg 邮件内容
* @param log 是否开启日志
*/
public static void sendMessage(String to, String subject, String msg, boolean log){
    try {
        Properties properties = new Properties();
        // 设置QQ邮件服务器,发件人邮箱地址必须是该邮箱服务器的邮箱
        properties.setProperty("mail.host","smtp.qq.com");  
        properties.setProperty("mail.transport.protocol","smtp");   // 指定发送协议为smtp
        properties.setProperty("mail.smtp.auth","true");        // 需要验证用户名密码

        // 邮件加密
        MailSSLSocketFactory factory = new MailSSLSocketFactory();
        factory.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable","true");
        properties.put("mail.smtp.ssl.socketFactory",factory);

        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("发件人邮箱xxxxxxx@xx.xxx","授权码");
            }
        });

        // 开启Session的debug模式,可以看到发送时的日志输出,不设置此属性默认为false,不输出日志
        session.setDebug(log);

        // 通过session获得transport对象,用于发送邮件
        Transport transport = session.getTransport();

        transport.connect("smtp.qq.com","发件人邮箱xxxxxxx@xx.xxx","授权码");

        // 创建邮件对象
        MimeMessage mimeMessage = new MimeMessage(session);

        // 指定发件人
        mimeMessage.setFrom(new InternetAddress("发件人邮箱xxxxxxx@xx.xxx"));

        // 指定收件人
        mimeMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(to));

        // 设置邮件主题
        mimeMessage.setSubject(subject);
        
        // 设置邮件正文文本
        mimeMessage.setContent(msg,"text/html;charset=utf-8");

        // 发送邮件
        transport.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
        
        // 关闭连接
        transport.close();
    } catch (GeneralSecurityException | MessagingException e) {
        System.out.println("邮件发送失败");
        e.printStackTrace();
    }
}

*发送一封完整的邮件

发送一封完整的邮件,包含主题,正文文本,图片附件,文件附件。

约定文件路径/图片路径数组各元素必须和其文件名/别名数组一一对应。

也可通过该方法发送简单邮件,把不需要的东西入参时传入null

这个方法我已经封装的尽可能完善了,可以直接拿去用

/**
* 发送一封完整的邮件,包含主题,正文文本,图片附件,文件附件
* @param to 收件人邮箱地址 不能为空
* @param subject 邮件主题 不能为空
* @param msg 正文文本html 不能为空
* @param imgPaths 图片本地路径 可以为空 为空则imgAlias也要为空(imgAlias不为空没有意义)
* @param imgAlias 图片别名,指定别名后可在正文html中通过cid引用该图片 可以为空
* @param filePaths 文件本地路径 可以为空 为空则fileAlias也要为空(fileNames不为空没有意义)
* @param fileNames 文件名 可以为空 文件名是收件方下载时的文件名,需要带文件后缀
* @param log 是否开启日志输出
*/
public static void sendMessage(@NotNull String to,@NotNull String subject, @NotNull String msg,
                               String[] imgPaths, String[] imgAlias,
                               String[] filePaths,String[] fileNames,boolean log){
    try {
        Properties properties = new Properties();
        properties.setProperty("mail.host","smtp.qq.com");
        properties.setProperty("mail.transport.protocol","smtp");
        properties.setProperty("mail.smtp.auth","true");

        MailSSLSocketFactory factory = new MailSSLSocketFactory();
        factory.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable","true");
        properties.put("mail.smtp.ssl.socketFactory",factory);

        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("发件人邮箱xxxxxxx@xx.xxx","授权码");
            }
        });
        session.setDebug(log);
        Transport transport = session.getTransport();
        transport.connect("smtp.qq.com","发件人邮箱xxxxxxx@xx.xxx","授权码");

        MimeMessage mimeMessage = new MimeMessage(session);
        mimeMessage.setFrom(new InternetAddress("发件人邮箱xxxxxxx@xx.xxx"));
        mimeMessage.setRecipient(Message.RecipientType.TO,new InternetAddress(to));
        mimeMessage.setSubject(subject);

        MimeMultipart contentParts = new MimeMultipart();   // 正文中的模块
        // 判断入参
        if (imgPaths != null && imgAlias != null && imgPaths.length == imgAlias.length){
            // 向正文中添加图片附件
            for (int i = 0; i < imgPaths.length; i++) {
                MimeBodyPart img = new MimeBodyPart();
                DataHandler handler = new DataHandler(new FileDataSource(imgPaths[i]));
                img.setDataHandler(handler);
                img.setContentID(imgAlias[i]);			// 设置图片别名
                contentParts.addBodyPart(img);
            }
        }
        // 邮件正文文本
        MimeBodyPart contentText = new MimeBodyPart();
        contentText.setContent(msg,"text/html;charset=utf-8");

        // 向正文模块中添加正文文本
        contentParts.addBodyPart(contentText);
        contentParts.setSubType("related");

        // 把正文模块设置到正文中
        MimeBodyPart content = new MimeBodyPart();      // 正文
        content.setContent(contentParts);

        MimeMultipart email = new MimeMultipart();      // 相当于整封邮件
        // 判断入参
        if (filePaths != null && fileNames != null && filePaths.length == fileNames.length){
            // 向邮件中添加文件附件
            for (int i = 0; i < filePaths.length; i++) {
                MimeBodyPart file = new MimeBodyPart();
                DataHandler handler = new DataHandler(new FileDataSource(filePaths[i]));
                file.setDataHandler(handler);
                file.setFileName(fileNames[i]);     // 设置文件名
                email.addBodyPart(file);
            }
        }

        email.addBodyPart(content);
        email.setSubType("mixed");

        mimeMessage.setContent(email);
        mimeMessage.saveChanges();

        transport.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
        transport.close();
    } catch (GeneralSecurityException | MessagingException e) {
        System.out.println("邮件发送失败");
        e.printStackTrace();
    }
}

Test

注意content中标签的src属性是"cid:first",就是上面给的图片别名,通过图片别名来引用该图片,因此需要一一对应

String[] imgPaths = {"src/1.jpg","src/2.jpg"};
String[] imgAlias = {"first","second"};
String[] filePaths = {"src/my.xml","src/db.properties"};
String[] fileAlias = {"my.xml","db.properties"};
//正文文本html
String content = "<img src='cid:first' style='width:100px;height:100px'/>" +
    "张三<h2 style='color:yellow;display:inline'>李四</h2>和王五" +
    "<img src='cid:second' style='width:100px;height:100px'/>";
// 全参数的完整邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,imgPaths,imgAlias,filePaths,fileAlias,true);
// 不带文件附件的邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,imgPaths,imgAlias,null,null,true);
// 不带图片附件的邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,null,null,filePaths,fileAlias,true);
// 仅正文的简单邮件
sendMessage("收件人邮箱地址","完整邮件测试",content,null,null,null,null,true);

...

// 我不知道可不可以发没有正文的邮件,但是我寻思应该没人会发正文都没有的邮件吧。。。

结果

测试时也可以自己给自己发,但是不建议发太多内容重复的邮件,容易被检测成垃圾邮件,如果发送成功找不到邮件,可以去垃圾箱看看。

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值