美文网首页
第四章:使用Springboot2整合JavaMail发送邮件

第四章:使用Springboot2整合JavaMail发送邮件

作者: 菜出意料 | 来源:发表于2019-03-05 15:48 被阅读0次

    本章目标

    整合JavaMail发送邮件,结果展示在文档末尾。

    搭建项目

    build.gradle依赖

        implementation 'org.springframework.boot:spring-boot-starter-mail'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    

    application.yml配置

    spring:
      mail:
        properties:
          mail:
            smtp:
              connectiontimeout: 5000
              timeout: 3000
              writetimeout: 5000
        host: smtp.126.com
        protocol: smtp
        port: 25
        username: 邮箱登录账号,如XXX@126.com
        password: 邮箱授权码
    
    1. host: 不同的邮箱对应的host不同,126邮箱为smtp.126.com
    2. username: 发件箱邮箱登录账号
    3. password: 邮箱授权码,如何获取不同邮箱的授权码可自行百度

    Tips:Springboot项目启动时,会根据application.yml中的mail配置实例化JavaMailSenderImpl实例mailSender,在使用mailSender时可以通过@Autowired直接注入。

    编写SpringTool工具类

    @Component
    public class SpringTool implements ApplicationContextAware {
        private static ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    
        public static <T> T getBean(String beanName, Class<T> clazz) {
            return applicationContext.getBean(beanName, clazz);
        }
    
        public static Object getBean(String beanName) {
            return getBean(beanName, null);
        }
    }
    

    SpringTool工具类主要根据beanName获取对应的对象

    编写MailUtil类

    public class MailUtil {
        private static JavaMailSenderImpl mailSender = SpringTool.getBean("mailSender", JavaMailSenderImpl.class);
    
        @RequiredArgsConstructor
        static class MimeMessageHelperBuilder {
            private final MimeMessage message;
    
            /**
             * 是否带附件 发送带附件和html格式的右键时必须为true
             */
            private final boolean multipart;
    
            /**
             * 收件人
             */
            private String to;
    
            /**
             * 右键主题
             */
            private String subject;
    
            /**
             * 右键内容
             */
            private String text;
    
            /**
             * 是否html格式的邮件
             */
            private boolean html;
    
            MimeMessageHelperBuilder to(String to) {
                this.to = to;
                return this;
            }
    
            MimeMessageHelperBuilder subject(String subject) {
                this.subject = subject;
                return this;
            }
    
            MimeMessageHelperBuilder text(String text) {
                this.text = text;
                return this;
            }
    
            MimeMessageHelperBuilder html(boolean html) {
                this.html = html;
                return this;
            }
    
            MimeMessageHelper build() throws MessagingException {
                MimeMessageHelper helper = new MimeMessageHelper(message, multipart);
                helper.setFrom(mailSender.getUsername());
    
                helper.setTo(to);
                helper.setText(text, html);
                helper.setSubject(subject);
    
                return helper;
            }
        }
    
        /**
         * 发送普通文本邮件
         * @param to       收件人
         * @param subject  邮件标题
         * @param text     邮件正文
         * @throws MessagingException
         */
        public static void setTextMail(String to, String subject, String text) throws MessagingException {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelperBuilder builder = new MimeMessageHelperBuilder(message, false);
            MimeMessageHelper helper = builder.to(to).subject(subject).text(text).build();
    
            sendMail(message);
        }
    
        /**
         * 发送带附件的邮件
         * @param to                    收件人
         * @param subject               邮件标题
         * @param text                  邮件正文
         * @param attachmentNamePathMap 附件名和附件路径组成的map
         * @throws MessagingException
         */
        public static void sendAttachmentMail(String to, String subject, String text, Map<String, String> attachmentNamePathMap) throws MessagingException {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelperBuilder builder = new MimeMessageHelperBuilder(message, true);
            MimeMessageHelper helper = builder.to(to).subject(subject).text(text).build();
    
            /**
             * 组装附件信息
             */
            attachmentNamePathMap.forEach((n, p) -> {
                FileSystemResource file = new FileSystemResource(new File(p));
                try {
                    helper.addAttachment(n, file);
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
            });
    
            sendMail(message);
        }
    
        /**
         * 发送html格式的邮件
         * @param to                收件人
         * @param subject           邮件标题
         * @param htmlText          html文档
         * @param inlineNamePathMap src名及路径对应的map
         * @throws MessagingException
         */
        public static void senHtmlMail(String to, String subject, String htmlText, Map<String, String> inlineNamePathMap) throws MessagingException {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelperBuilder builder = new MimeMessageHelperBuilder(message, true);
            MimeMessageHelper helper = builder.to(to).subject(subject).text(htmlText).html(true).build();
    
            /**
             * 组装html里img标签的src
             */
            inlineNamePathMap.forEach((n, p) -> {
                FileSystemResource file = new FileSystemResource(new File(p));
                try {
                    helper.addInline(n, file);
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
            });
    
            sendMail(message);
        }
    
        private static void sendMail(MimeMessage message) {
            mailSender.send(message);
        }
    
    }
    

    编写单元测试

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class Chapter04ApplicationTests {
        @Test
        public void testSendTextMail() throws MessagingException {
            MailUtil.setTextMail("***收件人邮箱***", "Text Mail", "测试JavaMail的Text mail");
        }
    
        @Test
        public void testSendAttachmentMail() throws MessagingException {
            Map<String, String> attachmentNamePathMap = new HashMap<>();
            attachmentNamePathMap.put("mysql-apt-config_0.8.12-1_all.deb", "/home/bobyco/Downloads/mysql-apt-config_0.8.12-1_all.deb");
            attachmentNamePathMap.put("desktop.jpg", "/home/bobyco/Pictures/desktop.jpg");
            attachmentNamePathMap.put("Paper_Architecture_by_Dmitri_Popov.jpg", "/home/bobyco/Pictures/Paper_Architecture_by_Dmitri_Popov.jpg");
            MailUtil.sendAttachmentMail("***收件人邮箱***", "Text Mail", "测试JavaMail发送带附件的邮件", attachmentNamePathMap);
        }
    
        @Test
        public void testSendHtmlMail() throws IOException, TemplateException, MessagingException {
            Map<String, String> inlineNamePathMap = new HashMap<>();
            inlineNamePathMap.put("desktop", "/home/bobyco/Pictures/desktop.jpg");
    
            StringBuffer s = new StringBuffer();
            s.append("<html>")
                .append("<head>")
                .append("<title>Welcome!</title>")
                .append("</head>")
                .append("<body>")
                .append("<h1>Welcome JavaMail!</h1>")
                .append("<p>Our latest product:<a href=\"http://baidu.com\"><img src=\"cid:desktop\" alt=\"\"></a></p>")
                .append("</body>")
                .append("</html>");
    
            MailUtil.senHtmlMail("***收件人邮箱***", "测试发送html格式的右键", s.toString(), inlineNamePathMap);
        }
    
        @Test
        public void contextLoads() {
        }
    
    }
    

    整合FreeMarker,使用FreeMarker模板创建邮件内容

    添加FreeMarker依赖

    implementation 'org.springframework.boot:spring-boot-starter-freemarker'
    

    在application.yml添加FreeMarker配置

      freemarker:
        template-loader-path: classpath:/templates/mail/
    

    Tips: Springboot项目启动时,会自动初始化id为freeMarkerConfiguration的freemarker.template.Configuration对象,在使用freeMarkerConfiguration时通过SpringTool获取或使用@Autowired注入都可!

    在MailUtil中添加sendTemplateMail方法

         private static Configuration cfg = SpringTool.getBean("freeMarkerConfiguration", Configuration.class);
        /**
         * 使用FreeMarker模板创建邮件内容
         * @param to                 收件人邮箱
         * @param subject            邮件标题
         * @param templatePath       模板路径
         * @param dataModel          模板对应的数据
         * @param inlineNamePathMap  src名及路径对应的map
         * @throws IOException
         * @throws TemplateException
         * @throws MessagingException
         */
        public static void sendTemplateMail(String to, String subject, String templatePath, Map dataModel, Map<String, String> inlineNamePathMap) throws IOException, TemplateException, MessagingException {
            Template temp = cfg.getTemplate(templatePath);
            String emailContent = FreeMarkerTemplateUtils.processTemplateIntoString(temp, dataModel);
            senHtmlMail(to, subject, emailContent, inlineNamePathMap);
        }
    

    在resources/templates/mail路径下编写MailHtmlTemplate.ftl文件

    <html>
    <head>
        <title>Welcome!</title>
    </head>
    <body>
    <h1>${title}!</h1>
    <p>Our latest product:<a href="http://baidu.com"><img src="cid:desktop" alt=""></a></p>
    </body>
    </html>
    

    编写单元测试

        @Test
        public void testSendTemplateMail() throws TemplateException, IOException, MessagingException {
            Map<String, String> inlineNamePathMap = new HashMap<>();
            inlineNamePathMap.put("desktop", "/home/bobyco/Pictures/desktop.jpg");
    
            Map dataModel = new HashMap();
            dataModel.put("title", "Welcome JavaMail Creating Email Content by Using a Templating Library!");
    
            MailUtil.sendTemplateMail("***收件人邮箱***", "测试发送使用模板创建正文的邮件", "MailHtmlTemplate.ftl", dataModel, inlineNamePathMap);
        }
    

    结果预览

    Tips: 如果在邮件里查看不到图片,请在电脑网页版邮箱中设置图片可见,即可浏览到图片!

    模板邮件.png
    html格式邮件.png
    带附件的邮件.png
    普通文本邮件.png

    源码路径

    本文源码地址:https://gitee.com/bobyco/sprintboot2_note_source/tree/master/chapter04
    end

    相关文章

      网友评论

          本文标题:第四章:使用Springboot2整合JavaMail发送邮件

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