使用Java发送邮件(IO流方式携带多个附件)

目录

场景与方案分析

开启QQ邮箱的SMTP服务

实体类准备

工具类准备

测试


场景与方案分析

最近博主做了一个项目,有一个业务场景是这样的:

后台管理员发布活动的时候可以上传与此活动相关的几个文件,用户报名某活动之后,将这些文件以附件的方式发送到其邮箱。

综上需求,我先介绍一下我们系统的情况:

1、文件可能上传多个,所以邮件的发送涉及到多附件上传;

2、我们的系统是前后端分离的,文件模块采用的是分布式的MinIO服务器,都是外网服务器上的线上文件,不是落在Java项目所运行的服务器磁盘上;

3、为了用户体验,邮件中的每个附件名称都要是用户上传时的原文件名称。

以上三点我们依次考虑,

第一点无所谓,我们只需要一个for循环即可;

第二点,因为我们的文件存储在专门的文件服务器上,所以我们需要读取文件的IO流,而不是指定本地磁盘上的文件路径;

第三点,我们在上传文件的时候记录了文件的原名称,在发送邮件时要用一个实体类声明文件的外网路径(用于获取IO流)以及文件的原名称。

开启QQ邮箱的SMTP服务

要发送邮件,就涉及到邮件发送方,在项目中一般是公司的企业账号,但是测试、学习用我们自己的QQ邮箱也是可以的,步骤很简单,在你的QQ邮箱里进行如下操作:

然后点击“账户”,往下滑:

点击“开启”,腾讯就会对你的身份进行验证,验证通过之后会给你一个授权码,将这个授权码保存好,作为你发送邮件的凭证。

实体类准备

我们将文件在外网的路径和原名称,用一个实体类来表示,在发送邮件时将该实体类的集合作为实参,达到多附件的效果。

package com.dosion.model.activity.entity.activity;

import lombok.Data;

/**
 *  <p>
 *      活动课件
 *  </p>
 *
 * @author 秋枫艳梦
 * @date 2019-12-03
 * */
@Data
public class ActivityCourse {
    //原文件名
    private String fileName;
    //文件的外网路径
    private String filePath;

    public ActivityCourse () {}
    public ActivityCourse (String fileName , String filePath) {
        this.fileName = fileName;
        this.filePath = filePath;
    }
}

工具类准备

package com.dosion.utils;

import com.alibaba.druid.util.StringUtils;
import com.dosion.model.activity.entity.activity.ActivityCourse;
import com.sun.mail.util.MailSSLSocketFactory;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.URLDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class EmailUtils {
    // 发件人电子邮箱
    private static String from = "你的QQ@qq.com";
    // 发件人电子邮箱授权码
    private static String pass = "你的授权码";
    //设置QQ邮箱服务器
    private static String host = "smtp.qq.com";
    

    /**
     * 发送带附件的邮件
     *
     * @param receive  收件人
     * @param subject  邮件主题
     * @param msg      邮件内容
     * @param courseList 课件附件的地址集合
     * @return
     * @throws GeneralSecurityException
     */
    public static void sendMail(String receive, String subject, String msg, List<ActivityCourse> courseList)
            throws GeneralSecurityException, MalformedURLException {

        // 获取系统属性
        Properties properties = System.getProperties();
        // 设置邮件服务器
        properties.setProperty("mail.smtp.host", host);
        properties.put("mail.smtp.auth", "true");
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable", "true");
        properties.put("mail.smtp.ssl.socketFactory", sf);
        // 获取默认session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() { // qq邮箱服务器账户、第三方登录授权码
                return new PasswordAuthentication(from, pass); // 发件人邮件用户名、密码
            }
        });

        try {
            //创建MimeMessage 对象
            MimeMessage message = new MimeMessage(session);
            //设置发送人
            message.setFrom(new InternetAddress(from));
            //设置接收人
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(receive));
            //设置邮件主题
            message.setSubject(subject);

            // 创建普通消息部分
            BodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText(msg);

            // 创建多重消息
            Multipart multipart = new MimeMultipart();
            // 设置多重消息的文本消息部分
            multipart.addBodyPart(messageBodyPart);
            //设置多重消息的附件部分
            int size = courseList.size();
            URL url;
            for (int i = 0; i < size; i++) {
                // 发送多个附件部分
                messageBodyPart = new MimeBodyPart();
                String path = courseList.get(i).getFilePath();
                String fileName = courseList.get(i).getFileName();
                // 设置要发送附件的文件IO流
                url = new URL(path);
                DataSource source = new URLDataSource(url);
                messageBodyPart.setDataHandler(new DataHandler(source));
                //设置附件名称
                messageBodyPart.setFileName(MimeUtility.encodeText(fileName));
                multipart.addBodyPart(messageBodyPart);
            }

            //设置最终的邮件
            message.setContent(multipart);
            //发送
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

测试

我们从京东上随便找一张图片:

再从我们的项目上拉一个xls文件:

duxiaohui.dosion.cc/activity/system/file/activity-ee5452ddeeb649dd8cc5ac63ef6c443d.xls

public static void main(String[] args) throws GeneralSecurityException, MalformedURLException {
        List<ActivityCourse> courseList = new ArrayList<>();
        courseList.add(new ActivityCourse("京东商品图片.png","https://img10.360buyimg.com/mobilecms/s500x500_jfs/t1/86469/24/3091/112229/5ddcc257E7f8899db/d51bbc277e44ed94.jpg"));
        courseList.add(new ActivityCourse("每日一答__模板.xls","http://duxiaohui.dosion.cc/activity/system/file/activity-ee5452ddeeb649dd8cc5ac63ef6c443d.xls"));
        sendMail("xxx@qq.com","多附件测试-博客","多附件正文,消息",courseList);
    }

执行这个main方法,可以看到已经收到邮件了:

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值