springboot2.x中的java mail使用相关模板,发送带静态资源与附件邮件到163邮箱

1.163邮箱配置

省略部分其他getter与setter方法

2.发送邮件的interface

3.发送邮件的接口实现类

import com.springcloud.my.config.MailFor163Config;
import com.springcloud.my.service.MailSendTo163Service;
import com.springcloud.my.utils.ContentTypeEnum;
import com.springcloud.my.utils.SetVelocityPro;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

/**
 * 发送邮件到163邮箱服务
 *
 * @Author Administrator
 * @Date 2020/6/26
 */
@Slf4j
@Service
public class MailSendTo163ServiceImpl implements MailSendTo163Service {


    @Autowired
    JavaMailSenderImpl javaMailSender;


    @Autowired
    MailFor163Config mailFor163Config;


    private DataHandler getDataHandlerByPath(String resourceLocation) throws FileNotFoundException {
        File file = ResourceUtils.getFile(resourceLocation);
        DataSource dataSource = new FileDataSource(file);
        return new DataHandler(dataSource);
    }

    private MimeBodyPart getImgBodyPart(String resourceLocation) throws MessagingException, FileNotFoundException {
        MimeBodyPart imagePort = new MimeBodyPart();
        imagePort.setDataHandler(getDataHandlerByPath(resourceLocation));
        imagePort.setHeader("Content-ID", "<image>");
        imagePort.setHeader("Content-Type", "image/png");
        imagePort.setDisposition(MimeBodyPart.INLINE);
        return imagePort;
    }

    /**
     * 参考了
     * http://www.javacui.com/java/397.html
     * https://blog.csdn.net/o_o814222198/article/details/100115423
     * 还是下边这个讲得清楚
     * https://www.cnblogs.com/ysocean/p/7666061.html
     * 使用Session.transport发送邮件到163邮箱
     */
    @Override
    public void sendMailByTransport(Map<String, Object> contentMap) {
        Properties props = new Properties();
        props.put("mail.smtp.host", mailFor163Config.getHost());
        //需要经过授权,也就是有户名和密码的校验,这样才能通过验证(一定要有这一条)
        props.put("mail.smtp.auth", true);
        //设置了附件名过长问题
        System.setProperty("mail.mime.splitlongparameters", "false");
        //用props对象构建一个session
        Session session = Session.getDefaultInstance(props);
        //用session为参数定义消息对象
        MimeMessage message = new MimeMessage(session);
        try {
            message.setFrom(mailFor163Config.getSendTo());
            String[] sendTo = new String[]{mailFor163Config.getSendTo()};
            InternetAddress[] Tos = new InternetAddress[sendTo.length];
            for (int i = 0; i < sendTo.length; i++) {
                Tos[i] = new InternetAddress(sendTo[i]);
            }
            message.addRecipients(Message.RecipientType.TO, Tos);
            //设置在发送给收信人之前给自己(发送方)抄送一份,不然会被当成垃圾邮件,报554错
            message.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(mailFor163Config.getSendTo()));
            //加载标题----
            message.setSubject(MimeUtility.encodeText(String.valueOf(contentMap.get("subject"))));

            String imgPath2 = String.valueOf(contentMap.get("imgPath2"));

            // 创建图片部分
            MimeBodyPart imagePort = getImgBodyPart(String.valueOf(contentMap.get("imgPath1")));
            MimeBodyPart imagePort2 = getImgBodyPart(imgPath2);

            // TODO 这里设置的png_1、png_2分别于对应下边字符串html中的img的cid对应
            imagePort.setContentID("png_1");
            imagePort2.setContentID("png_2");

            //设置邮件的文本内容
            BodyPart htmlText = new MimeBodyPart();
            htmlText.setContent(contentMap.get("htmlStr"), "text/html;charset=UTF-8");

            // 将图片与文本结合在一起
            MimeMultipart textAndImgPart = new MimeMultipart();
            textAndImgPart.addBodyPart(htmlText);
            textAndImgPart.addBodyPart(imagePort);
            textAndImgPart.addBodyPart(imagePort2);
            // 设置为关联关系
            textAndImgPart.setSubType("related");

            // 将文本与图片混合在一起
            MimeBodyPart textAndImgBodyPart = new MimeBodyPart();
            textAndImgBodyPart.setContent(textAndImgPart);

            //创建附件内容
            BodyPart attachmentBodyPart = new MimeBodyPart();

            attachmentBodyPart.setDataHandler(getDataHandlerByPath(imgPath2));
            // 使用MimeUtility.encodeWord编码
            attachmentBodyPart.setFileName(MimeUtility.encodeWord(ResourceUtils.getFile(imgPath2).getName()));


            // 设置文本+图片+附件的混合体,向multipart对象中添加邮件的各部分内容
            MimeMultipart multipart = new MimeMultipart();
            multipart.addBodyPart(textAndImgBodyPart);
            multipart.addBodyPart(attachmentBodyPart);

            // 设置为混合的
            multipart.setSubType("mixed");

            //将multipart对象放到message中
            message.setContent(multipart);
            message.setSentDate(new Date());

            message.saveChanges();
            Transport transport = session.getTransport("smtp");

            long start = System.currentTimeMillis();

            //连接服务器的邮箱,分别是host,收件人,授权码
            transport.connect(mailFor163Config.getHost(), mailFor163Config.getSendTo(), mailFor163Config.getAuthCode());
            //把邮件发送出去
            transport.sendMessage(message, message.getAllRecipients());

            log.info("Session.transport发送邮件到163邮箱: {} 毫秒", System.currentTimeMillis() - start);

            transport.close();//关闭连接
        } catch (MessagingException | FileNotFoundException | UnsupportedEncodingException e) {
            log.error("Session.transport发送邮件到163邮箱异常", e);
        }
    }


    /**
     * 发送html以及带附件到163邮箱,建议使用该方式
     * 部分参考自 https://www.cnblogs.com/moris5013/p/9729422.html
     * @param contentMap 内容
     */
    public void sendMailByMailSender(Map<String, Object> contentMap) {

        javaMailSender.setHost(mailFor163Config.getHost());
        // TODO 设置授权码这里不加会报错:com.sun.mail.smtp.SMTPSenderFailedException: 553 authentication is required,163 smtp1,GdxpCgAn6l7m8fRe9vGAFA--.93S2 1593111024
        javaMailSender.setPassword(mailFor163Config.getAuthCode());
        javaMailSender.setUsername(mailFor163Config.getSendTo());
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        //设置多个收件人
        String[] sendTo = new String[]{mailFor163Config.getSendTo()};
        InternetAddress[] Tos = new InternetAddress[sendTo.length];
        Transport transport = null;
        try {

            for (int i = 0; i < sendTo.length; i++) {
                Tos[i] = new InternetAddress(sendTo[i]);
            }
            //设置在发送给收信人之前给自己(发送方)抄送一份,不然会被当成垃圾邮件,报554错
            mimeMessage.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(mailFor163Config.getSendTo()));
            mimeMessage.addRecipients(Message.RecipientType.TO, Tos);

            //加载标题
            mimeMessage.setSubject(MimeUtility.encodeText("我是来测试的"));

            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
            messageHelper.setFrom(mailFor163Config.getSendTo());
            messageHelper.setTo(mailFor163Config.getSendTo());

            StringWriter writer = new StringWriter();

            //实例化一个VelocityEngine对象
            Properties properties = SetVelocityPro.getVelocityProperties();
            VelocityEngine velocityEngine = new VelocityEngine(properties);
            velocityEngine.init();
            Template template = velocityEngine.getTemplate("templates/mail-vm.vm");

            VelocityContext velocityContext = new VelocityContext();
            velocityContext.put("test", contentMap.get("urlTest") + "-------" + contentMap.get("date"));

            template.merge(velocityContext, writer);
            // 用来让text内容以html格式进行展示
            messageHelper.setText(writer.toString(), true);

            messageHelper.addInline("identifier01", (File) contentMap.get("imgPath"));
            // 添加图片附件
            File pngFile = (File) contentMap.get("png");
            messageHelper.addAttachment(MimeUtility.encodeWord(pngFile.getName()), new FileSystemResource(pngFile), ContentTypeEnum.PNG.getCentType());

            long start = System.currentTimeMillis();

            javaMailSender.send(mimeMessage);

            log.info("javaMailSender发送邮件到163邮箱: {} 毫秒", System.currentTimeMillis() - start);
        } catch (MessagingException | UnsupportedEncodingException e) {
            log.error("使用javaMailSender发送邮件到163邮箱异常", e);
        }
    }

4.控制器代码

    @RequestMapping("/send163")
    public String sendMailTo163() {
        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("subject", "我是来测试的");
        contentMap.put("imgPath1", "classpath:static/img/test.png");
        contentMap.put("imgPath2", "classpath:static/img/1.png");
        String html = "<div style='position: absolute; margin: 50px 0 0 100px ;width: 100%;'>"
                + "<font color='red'>这是来自一位苦逼程序猿的测试</font><br/>"
                + "<img src='cid:png_1' style='margin: 20px 0 0 0;'/>"
                + "<img src='cid:png_2' style='margin: 20px 0 0 10px;'/>"
                + "</div>";
        contentMap.put("htmlStr", html);

        mailSendTo163Service.sendMailByTransport(contentMap);
        return "发送163邮件成功~~~~~";

    }

    @RequestMapping("/sendMailTo163New")
    public String sendMailTo163New() throws FileNotFoundException {
        Map<String, Object> map = new HashMap<>();
        map.put("urlTest", UUID.randomUUID());
        map.put("date", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date()));
        map.put("imgPath", ResourceUtils.getFile("classpath:static/img/test.png"));
        map.put("png", ResourceUtils.getFile("classpath:static/img/1.png"));

        mailSendTo163Service.sendMailByMailSender(map);
        return "使用velocity发送邮件到网易成功~~~~~";
    }

5.application.yml设置

6.测试发送邮件的截图

7.相关的图片请自己放到resources指定目录下即可,文件名保持一致就可以

至于相关模板,请参见我的上一篇博客:

https://blog.csdn.net/l244112311/article/details/106954539

猜你喜欢

转载自blog.csdn.net/l244112311/article/details/106965388