maven依赖包如下
org.springframework.boot
spring-boot-starter-mail
com.sun.mail
javax.mail
1.6.0
一、登录QQ邮箱,点击【设置】后再点击【账户】,再往下翻,找到【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务】这一栏
开启如图所示中的三项(非强制,这三项是根据需要开通的),我这里要求开启第一个
注意图中圈出的【生成授权码】,点击后可以生成一个授权码,然后记录它,待会项目中配置需要
二、在配置文件【application.yml】写好配置,我的配置文件区分了环境(大家可以无视),默认的应该是application.yml
参数说明:【host】、【port】、【debug】默认配置就好了,debug的话生产建议关掉,【username】是你的QQ邮箱号,【password】是你刚才申请的授权码
三、在代码中建立一个Configuration,用来加载刚才在 application.yml 中配置的数据。这里特别提一下,我采用@Bean的方式注入 JavaMailSenderImpl,在后面用的时候直接以 @Autowired 注入该类
package cn.xt.app.base.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import java.util.Properties;
/**
* create: xiaotian
* date: 2018/10/20
*/
@Configuration
public class MailConfig {
@Value("${mail.host}")
private String mailHost;
@Value("${mail.port}")
private Integer mailPort;
@Value("${mail.debug}")
private String mailDebug;
@Value("${mail.username}")
private String mailUsername;
@Value("${mail.password}")
private String mailPassword;
@Bean(name = "javaMailSender")
public JavaMailSenderImpl javaMailSender(){
// 默认配置相关
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost(mailHost);
javaMailSender.setPort(mailPort);
javaMailSender.setUsername(mailUsername);
javaMailSender.setPassword(mailPassword);
// 认证相关
Properties properties = new Properties();
properties.setProperty("mail.host", mailHost);
properties.setProperty("mail.transport.protocol", "smtp");
properties.setProperty("mail.smtp.auth", "true");
properties.setProperty("mail.smtp.port", String.valueOf(mailPort));
properties.setProperty("mail.smtp.socketFactory.port", String.valueOf(mailPort));
properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
javaMailSender.setJavaMailProperties(properties);
return javaMailSender;
}
}
四、接下来编写一个接口,我这里叫【MailBiz】,主要是定义一些使用的方法,例如有的可以发附件,有的方法可以抄送等等
package cn.xt.app.biz.mail;
import java.util.List;
/**
* create: xiaotian
* date: 2018/10/20
*/
public interface MailBiz {
void sendMail(String subject, String body, String from, String[] to) throws Exception;
void sendMail(String subject, String body, String from, String[] cc, String[] to) throws Exception;
void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to) throws Exception;
void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to, List attachPathList) throws Exception;
}
五、接下来定义一个实现类【MailBizService】来实现【MailBiz】这个接口
package cn.xt.app.service.mail;
import cn.xt.app.biz.mail.MailBiz;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.List;
/**
* create: xiaotian
* date: 2018/10/20
*/
@Slf4j
@Service
public class MailBizService implements MailBiz {
@Autowired
private JavaMailSenderImpl javaMailSender;
/**
* 发送邮件
*
* @param subject 主题
* @param body 内容
* @param from 发件人
* @param to 收件人[多个]
*/
public void sendMail(String subject, String body, String from, String[] to) throws Exception {
sendMail(subject, body, from, null, to);
}
/**
* 发送邮件
*
* @param subject 主题
* @param body 内容
* @param from 发件人
* @param cc 抄送人[多个]
* @param to 收件人[多个]
*/
public void sendMail(String subject, String body, String from, String[] cc, String[] to) throws Exception {
sendMail(subject, body, false, from, cc, to);
}
/**
* 发送邮件
*
* @param subject 主题
* @param body 内容
* @param html 是否为html格式
* @param from 发件人
* @param cc 抄送人[多个]
* @param to 收件人[多个]
*/
public void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to) throws Exception {
sendMail(subject, body, html, from, cc, to, null);
}
/**
* 发送邮件
*
* @param subject 主题
* @param body 内容
* @param html 是否为html格式
* @param from 发件人
* @param cc 抄送人[多个]
* @param to 收件人[多个]
* @param attachPathList 附件路径
*/
public void sendMail(String subject, String body, boolean html, String from, String[] cc, String[] to, List attachPathList) throws Exception {
try {
MimeMessage parentMimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(parentMimeMessage, true, "utf-8");
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setFrom(new InternetAddress(from));
mimeMessageHelper.setSentDate(new Date());
// 设置收件人地址
mimeMessageHelper.setTo(to);
// 设置抄送人
if (!StringUtils.isEmpty(cc)) {
mimeMessageHelper.setCc(cc);
}
// 设置正文
mimeMessageHelper.setText(body, html);
// 设置附件
if (!CollectionUtils.isEmpty(attachPathList)) {
Multipart multipart = new MimeMultipart();
for (String attachPath : attachPathList) {
MimeBodyPart mimeBodyPart = new MimeBodyPart();
DataHandler dataHandler = new DataHandler(new FileDataSource(attachPath));
mimeBodyPart.setDataHandler(dataHandler);
mimeBodyPart.setFileName(dataHandler.getName());
multipart.addBodyPart(mimeBodyPart);
}
parentMimeMessage.setContent(multipart);
}
// 正式发送邮件
javaMailSender.send(parentMimeMessage);
} catch (Exception e) {
log.error("发送邮件失败:{}", e);
throw e;
}
}
}
至此,发送邮件的代码到这里就这完成了,可以写单元测试来看下效果。这些代码都是经过我的严格测试的,功能都是OK的。
我这里发送邮件的代码以供大家参考:
这里特别指出一下:【mailFrom】也就是发件人,必须是你自己的邮箱号
@Autowired
private MailBiz mailBiz;
@Value("${mail.username}")
private String mailFrom;
@Override
public ResultResponse sendMail(SendEmailRequest request) {
ResultResponse response = new ResultResponse();
try {
mailBiz.sendMail(request.getSubject(), request.getBody(), request.getHtml(), //
mailFrom, request.getCc(), request.getTo(), request.getAttachPathList());
response.setCode(ApplicationStatusEnum.SUCCESS.getCode());
response.setMessage("邮件发送成功");
} catch (Exception e) {
response.setCode(ApplicationStatusEnum.FAILED.getCode());
response.setMessage("邮件发送失败");
}
return response;
}
总结:利用 yml 配置一些参数,比直接写在代码里面灵活,以 @Value 注解把配置文件中的值注入到变量中。另外在Config中以@Bean的方式将一些配置初始化,相当于核心工作交给Spring去管理,不易出错,且比较好维护。
代码中如有不足之处请大家留言指正!