【工具】发邮件(javamail)

【踩坑】
若smtp发送邮件的邮箱平台只有登陆账号及密码而没有授权码,需要写验证类,否则可能出现在本地可以正常发邮件,而到了服务器上则认证不通过。

@Service
public class SaiDaEmailService {

    private static final Logger log = LoggerFactory.getLogger(SaiDaEmailService.class);

    @Autowired
    private SaiDaOutFileService saiDaOutFileService;

    /**
     * 邮箱相关配置
     */
    private static String host;//邮箱服务器
    private static String port;//端口号
    private static String sendUsername;//发件人邮箱
    private static String sendPassword;//发件人密码
    private static String sendName;//发件人别名
    private static String fileName;//附件文件地址
    private static String content;//邮件内容
    private static String title;//邮件标题
    private static final List<String> toReceiverList = new ArrayList<>();//收件人邮箱
    private static final List<String> copyReceiverList = new ArrayList<>();//抄送人邮箱

    /**
     * @Description 赛达发送邮件
     * @Param
     **/
    public void sendEmail() {
        try {
            log.info("sendEmail() - send email start!");
            //若无配置数据,取数
            if (StringUtils.isEmpty(host)) {
                getConfigInfo();
            }

            //配置smtp
            Properties props = System.getProperties();
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.port", port);
            props.put("mail.smtp.connectiontimeout", 10000);
            props.put("mail.smtp.timeout", 30000);

            // 邮箱设置SSL加密
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.ssl.socketFactory", sf);
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");

            //创建定义整个应用程序所需的环境信息的 Session 对象
            Authenticator auth = new PopupAuthenticator(sendUsername, sendPassword);
            Session session = Session.getInstance(props, auth);
            session.setDebug(true);
            //创建邮件,传入session对象
            MimeMessage mime = complexEmail(session);
            if (mime == null) {
                log.warn("sendEmail() - email content is null, send fail !");
                return;
            }
            //通过session获取transport对象
            SMTPTransport trans = (SMTPTransport) session.getTransport("smtp");
            //通过transport对象邮箱用户名和授权码连接邮箱服务器
            trans.connect(host, sendUsername, sendPassword);
            //发送邮件
            trans.sendMessage(mime, mime.getAllRecipients());
            //关闭链接
            trans.close();
            log.info("sendEmail() - send email end !");
        } catch (Exception e) {
            log.warn("sendEmail() - send email error, " + e);
        }
    }

    /**
     * @return MimeMessage
     * @Description 处理邮件信息
     * @Param session
     **/
    private MimeMessage complexEmail(Session session) {
        try {
            log.info("complexEmail() - complex email start !");
            //消息的固定信息
            MimeMessage mimeMessage = new MimeMessage(session);
            //发件人
            mimeMessage.setFrom(new InternetAddress(sendUsername, sendName, "utf-8"));
            //收件人
            // 添加收件人
            if (toReceiverList.size() > 0) {
                mimeMessage.setRecipients(Message.RecipientType.TO, getInternetAddress(toReceiverList));
            } else {
                log.warn("complexEmail() - receiver is null !");
                return null;
            }
            // 添加抄送人
            if (copyReceiverList.size() > 0) {
                mimeMessage.setRecipients(Message.RecipientType.CC, getInternetAddress(copyReceiverList));
            }
            //设置赛达月份
            Calendar cal = Calendar.getInstance();
            String date = cal.get(Calendar.YEAR) + "年" + cal.get(Calendar.MONTH);
            //邮件标题
            title = title.replaceAll("X", date);
            mimeMessage.setSubject(title);
            //准备文本
            MimeBodyPart text = new MimeBodyPart();
            content = content.replaceAll("X", date);
            text.setContent(content, SaiDaGlobal.CONTENT_TYPE);
            //附件
            ByteArrayOutputStream os = saiDaOutFileService.outFileFromEmail();
            if (os == null) {
                log.warn("complexEmail() - saiDa excel data is null !");
                return null;
            }
            DataSource source = new ByteArrayDataSource(os.toByteArray(), SaiDaGlobal.SOURCE_TYPE);
            MimeBodyPart appendix = new MimeBodyPart();
            appendix.setDataHandler(new DataHandler(source));
            fileName = fileName.replaceAll("X", date);
            appendix.setFileName(MimeUtility.encodeText(fileName));
            //拼装邮件正文
            MimeMultipart mimeMultipart = new MimeMultipart();
            mimeMultipart.addBodyPart(text);
            mimeMultipart.setSubType("related");
            //将拼装好的正文内容设置为主体
            MimeBodyPart contentText = new MimeBodyPart();
            contentText.setContent(mimeMultipart);
            //拼接附件
            MimeMultipart allFile = new MimeMultipart();
            allFile.addBodyPart(appendix);//附件
            allFile.addBodyPart(contentText);//正文
            allFile.setSubType("mixed"); //正文和附件都存在邮件中,所有类型设置为mixed
            //放到Message消息中
            mimeMessage.setContent(allFile);
            //保存修改
            mimeMessage.saveChanges();

            log.info("complexEmail() - complex email end !");
            return mimeMessage;
        } catch (MessagingException | UnsupportedEncodingException e) {
            log.warn("complexEmail() - complex email error, " + e);
            return null;
        }
    }

    /**
     * @Description 获取邮件相关配置信息
     * @Param
     **/
    private static void getConfigInfo() {
        try {
            log.info("getConfigInfo() - get email config start!");
            //从配置文件中得到
            StringBuilder resStr = new StringBuilder();
            ResourceBundle rb = ConfigUtil.getPropertiesConfig(SaiDaGlobal.EMAIL_CONFIG_PATH);
            host = rb.getString("mail.host");
            port = rb.getString("mail.port");
            sendUsername = rb.getString("send.username");
            sendPassword = rb.getString("send.password");
            sendName = rb.getString("send.alias");
            fileName = rb.getString("mail.file.name");
            content = rb.getString("mail.content");
            title = rb.getString("mail.title");
            resStr.append("host = ").append(host)
                    .append("host = ").append(port)
                    .append("sendUsername = ").append(sendUsername)
                    .append("sendPassword = ").append(sendPassword)
                    .append("sendName = ").append(sendName)
                    .append("fileName = ").append(fileName)
                    .append("content = ").append(content)
                    .append("title = ").append(title);
            //得到全部的收件人
            int toReceiverCount = 1;
            while (!StringUtils.isEmpty(rb.getString("to.username" + toReceiverCount))) {
                if (!toReceiverList.contains(rb.getString("to.username" + toReceiverCount))) {
                    toReceiverList.add(rb.getString("to.username" + toReceiverCount));
                    resStr.append("toReceiver" + toReceiverCount + " = ").append(rb.getString("to.username" + toReceiverCount));
                }
                toReceiverCount++;
            }
            //得到全部的抄送人
            int copyReceiverCount = 1;
            while (!StringUtils.isEmpty(rb.getString("copy.username" + copyReceiverCount))) {
                if (!toReceiverList.contains(rb.getString("copy.username" + copyReceiverCount))) {
                    toReceiverList.add(rb.getString("copy.username" + copyReceiverCount));
                    resStr.append("copyReceiver" + copyReceiverCount + " = ").append(rb.getString("copy.username" + copyReceiverCount));
                }
                copyReceiverCount++;
            }
            log.info("getConfigInfo() - get email config end, " + resStr);
        } catch (Exception e) {
            log.warn("getConfigInfo() - get email config error, " + e);
        }
    }

    /**
     * @return InternetAddress[]
     * @Description 处理收件人、抄送人格式
     * @Param List<String>
     **/
    private static InternetAddress[] getInternetAddress(List<String> list) {
        int len = list.size();
        if (len == 0) {
            return null;
        }
        InternetAddress[] internetAddresses = new InternetAddress[len];
        for (int i = 0; i < len; i++) {
            try {
                internetAddresses[i] = new InternetAddress(list.get(i));
            } catch (AddressException e) {
                e.printStackTrace();
            }
        }
        return internetAddresses;
    }
}

/**
 * 邮箱验证类
 * @author Huangyu
 * @date 2021/8/6
 */
public class PopupAuthenticator extends Authenticator {
    private String username;
    private String password;

    public PopupAuthenticator(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(this.username, this.password);
    }
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值