使用SpringBoot发送邮件
邮件发送其实是一个非常常见的需求,用户注册,找回密码等地方,都会用到,Spring Boot 中对于邮件发送,提供了相关的自动化配置类,使得邮件发送变得非常容易。
1、前置工作
目前国内大部分的邮件服务商都不允许直接使用用户名/密码的方式来在代码中发送邮件,都是要先申请授权码,这里以 QQ 邮箱为例,向大家演示授权码的申请流程:
首先我们需要先登录 QQ 邮箱网页版,点击上方的设置按钮:然后点击账户选项卡:在账户选项卡中找到开启POP3/SMTP选项,如下:
点击开启,开启相关功能,开启过程需要手机号码验证,按照步骤操作即可,不赘述。开启成功之后,即可获取一个授权码,将该号码保存好,一会使用。
2、引入依赖、配置邮箱基本信息
<!--集成发送邮件的功能--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
然后在yml配置文件中进行配置
spring:mail:host: smtp.qq.com # 设置邮箱主机port:587# SMTP 服务器的端口username: [email protected] # 设置用户名password: yyds # 设置密码,该处的密码是QQ邮箱开启SMTP的授权码而非QQ密码mail:from: ${spring.mail.username}to: [email protected]
做完这些之后,Spring Boot 就会自动帮我们配置好邮件发送类,相关的配置在
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration
类中,部分源码如下:
@Configuration@ConditionalOnClass({MimeMessage.class,MimeType.class,MailSender.class})@ConditionalOnMissingBean(MailSender.class)@Conditional(MailSenderCondition.class)@EnableConfigurationProperties(MailProperties.class)@Import({MailSenderJndiConfiguration.class,MailSenderPropertiesConfiguration.class})publicclassMailSenderAutoConfiguration{}
可以看到,导入了另外一个配置
MailSenderPropertiesConfiguration
类,这个类中,提供了邮件发送相关的工具类,源码如下:
@Configuration@ConditionalOnProperty(prefix ="spring.mail", name ="host")classMailSenderPropertiesConfiguration{privatefinalMailProperties properties;MailSenderPropertiesConfiguration(MailProperties properties){this.properties = properties;}@Bean@ConditionalOnMissingBeanpublicJavaMailSenderImplmailSender(){JavaMailSenderImpl sender =newJavaMailSenderImpl();applyProperties(sender);return sender;}}
可以看到,这里创建了一个
JavaMailSenderImpl
的实例,
JavaMailSenderImpl
是
JavaMailSender
的一个实现,我们将使用
JavaMailSenderImpl
来完成邮件的发送工作。
3、Service层代码
自定义的MailProperties配置类,用于解析mail开头的配置属性
packagecom.yyds.domain;importlombok.Data;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.stereotype.Component;@Data@Component@ConfigurationProperties(prefix ="mail")publicclassMailProperties{privateString from;privateStringto;}
service层
packagecom.yyds.service;importfreemarker.template.TemplateException;importjavax.mail.MessagingException;importjava.io.IOException;importjava.util.Map;publicinterfaceMailService{voidsendSimpleMail(String subject,String text);voidsendHtmlMail(String subject,String text,Map<String,String> attachmentMap)throwsMessagingException;voidsendTemplateMail(String subject,Map<String,Object> params)throwsMessagingException,IOException,TemplateException;}
packagecom.yyds.service.impl;importcom.yyds.domain.MailProperties;importcom.yyds.service.MailService;importfreemarker.cache.ClassTemplateLoader;importfreemarker.cache.TemplateLoader;importfreemarker.template.Configuration;importfreemarker.template.Template;importfreemarker.template.TemplateException;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.core.io.FileSystemResource;importorg.springframework.mail.SimpleMailMessage;importorg.springframework.mail.javamail.JavaMailSender;importorg.springframework.mail.javamail.MimeMessageHelper;importorg.springframework.stereotype.Service;importorg.springframework.ui.freemarker.FreeMarkerTemplateUtils;importorg.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;importjavax.mail.MessagingException;importjavax.mail.internet.MimeMessage;importjava.io.File;importjava.io.IOException;importjava.util.Map;@ServicepublicclassMailServiceImplimplementsMailService{@AutowiredprivateJavaMailSender javaMailSender;@AutowiredprivateMailProperties myMailProperties;/**
* 发送简单文本邮件
*/@OverridepublicvoidsendSimpleMail(String subject,String text){SimpleMailMessage mailMessage =newSimpleMailMessage();
mailMessage.setFrom(myMailProperties.getFrom());
mailMessage.setTo(myMailProperties.getTo());
mailMessage.setSubject(subject);
mailMessage.setText(text);
javaMailSender.send(mailMessage);}/**
* 发送带有链接和附件的复杂邮件
*/@OverridepublicvoidsendHtmlMail(String subject,String text,Map<String,String> attachmentMap)throwsMessagingException{MimeMessage mimeMessage = javaMailSender.createMimeMessage();//是否发送的邮件是富文本(附件,图片,html等)MimeMessageHelper messageHelper =newMimeMessageHelper(mimeMessage,true);
messageHelper.setFrom(myMailProperties.getFrom());
messageHelper.setTo(myMailProperties.getTo());
messageHelper.setSubject(subject);
messageHelper.setText(text,true);//重点,默认为false,显示原始html代码,无效果if(attachmentMap !=null){
attachmentMap.entrySet().stream().forEach(entrySet ->{try{File file =newFile(entrySet.getValue());if(file.exists()){
messageHelper.addAttachment(entrySet.getKey(),newFileSystemResource(file));}}catch(MessagingException e){
e.printStackTrace();}});}
javaMailSender.send(mimeMessage);}/**
* 发送模版邮件
*/@OverridepublicvoidsendTemplateMail(String subject,Map<String,Object> params)throwsMessagingException,IOException,TemplateException{MimeMessage mimeMessage = javaMailSender.createMimeMessage();MimeMessageHelper helper =newMimeMessageHelper(mimeMessage,true);
helper.setFrom(myMailProperties.getFrom());
helper.setTo(myMailProperties.getTo());freemarker.template.Configuration configuration =newfreemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_19);TemplateLoader templateLoader =newClassTemplateLoader(this.getClass(),"/templates/");
configuration.setTemplateLoader(templateLoader);Template template = configuration.getTemplate("mail.ftl");String html =FreeMarkerTemplateUtils.processTemplateIntoString(template, params);
helper.setSubject(subject);
helper.setText(html,true);//重点,默认为false,显示原始html代码,无效果
javaMailSender.send(mimeMessage);}}
4、发送邮件
4.1 测试发送简单文本邮件
@SpringBootTest(classes =BootStartApplication.class)publicclassMimeMailTest{@AutowiredprivateMailService mailService;@TestpublicvoidsendMail(){
mailService.sendSimpleMail("测试Springboot发送邮件","发送邮件...");}}
4.2 测试发送带有链接和附件的复杂邮件
packagecom.yyds;importcom.yyds.service.MailService;importfreemarker.template.TemplateException;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importjavax.mail.MessagingException;importjava.io.IOException;importjava.util.HashMap;importjava.util.Map;@SpringBootTest(classes =BootStartApplication.class)publicclassMimeMailTest{@AutowiredprivateMailService mailService;@TestpublicvoidtestMail()throwsMessagingException{Map<String,String> attachmentMap =newHashMap<>();
attachmentMap.put("附件","D:\\D_ENL_MRO数据统计.xlsx");
mailService.sendHtmlMail("测试Springboot发送带附件的邮件2","欢迎进入<a href=\"http://www.baidu.com\">百度首页</a>", attachmentMap);}}
4.3 测试发送发送模版邮件
首先需要引入 Freemarker 依赖:
<!--整合freemarker--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency>
然后在
resources/templates
目录下创建一个
mail.ftl
作为邮件发送模板:
<html><body><h3>你好, <spanstyle="color: red;">${username}</span>, 这是一封模板邮件!</h3></body></html>
packagecom.yyds;importcom.yyds.service.MailService;importfreemarker.template.TemplateException;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importjavax.mail.MessagingException;importjava.io.IOException;importjava.util.HashMap;importjava.util.Map;@SpringBootTest(classes =BootStartApplication.class)publicclassMimeMailTest{@AutowiredprivateMailService mailService;@TestpublicvoidtestFreemarkerMail()throwsMessagingException,IOException,TemplateException{Map<String,Object> params =newHashMap<>();
params.put("username","Tom");
mailService.sendTemplateMail("测试Springboot发送模版邮件", params);}}
版权归原作者 undo_try 所有, 如有侵权,请联系我们删除。