【1】引入starter-mail与邮件自动配置
pom文件依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
该starter引入如下依赖,可以看到其内部引用的是javax.mail,groupId为com.sun.mail:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
SpringBoot中对邮件任务做了自动配置,自动配置类MailSenderAutoConfiguration。
源码如下:
@Configuration
@ConditionalOnClass({ MimeMessage.class, MimeType.class })
@ConditionalOnMissingBean(MailSender.class)
@Conditional(MailSenderCondition.class)
@EnableConfigurationProperties(MailProperties.class)
@Import(JndiSessionConfiguration.class)
public class MailSenderAutoConfiguration {
private final MailProperties properties;
private final Session session;
public MailSenderAutoConfiguration(MailProperties properties,
ObjectProvider<Session> session) {
this.properties = properties;
this.session = session.getIfAvailable();
}
// 用来发送邮件的实现类
@Bean
public JavaMailSenderImpl mailSender() {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
if (this.session != null) {
sender.setSession(this.session);
}
else {
applyProperties(sender);
}
return sender;
}
private void applyProperties(JavaMailSenderImpl sender) {
//设置Host
sender.setHost(this.properties.getHost());
if (this.properties.getPort() != null) {
sender.setPort(this.properties.getPort());
}
//设置账户
sender.setUsername(this.properties.getUsername());
//设置密码--通常是服务授权码
sender.setPassword(this.properties.getPassword());
//设置protocol 如smtp pope imap
sender.setProtocol(this.properties.getProtocol());
//字符编码,默认UTF-8
if (this.properties.getDefaultEncoding() != null) {
sender.setDefaultEncoding(this.properties.getDefaultEncoding().name());
}
//其他属性
if (!this.properties.getProperties().isEmpty()) {
sender.setJavaMailProperties(asProperties(this.properties.getProperties()));
}
}
private Properties asProperties(Map<String, String> source) {
Properties properties = new Properties();
properties.putAll(source);
return properties;
}
/**
* Condition to trigger the creation of a {@link JavaMailSenderImpl}. This kicks in if
* either the host or jndi name property is set.
*/
static class MailSenderCondition extends AnyNestedCondition {
MailSenderCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnProperty(prefix = "spring.mail", name = "host")
static class HostProperty {
}
@ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name")
static class JndiNameProperty {
}
}
}
JavaMailSenderImpl继承类示意图如下:
邮件属性配置类MailProperties源码示例如下:
@ConfigurationProperties(prefix = "spring.mail")
public class MailProperties {
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
//服务器地址,如smtp.163.com
private String host;
//发送端口,如25
private Integer port;
//账户
private String username;
//密码--通常用服务授权码
private String password;
private String protocol = "smtp";
//默认信息编码字符集
private Charset defaultEncoding = DEFAULT_CHARSET;
//其他配置信息
private Map<String, String> properties = new HashMap<String, String>();
/**
* Session JNDI name. When set, takes precedence to others mail settings.
*/
private String jndiName;
/**
* Test that the mail server is available on startup.
*/
private boolean testConnection;
//...
}
【2】简单消息发送示例
这里使用163邮箱服务器向QQ邮箱发送邮件,只是简单文本。
application.properties对邮件属性配置实例如下:
spring.mail.username=你的邮箱账号
# 这里使用授权码
spring.mail.password=xxxxx
spring.mail.host=smtp.163.com
spring.mail.protocol=smtp
spring.mail.port=25
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.test-connection=true
自动装配JavaMailSenderImpl,测试代码如下:
@Autowired
JavaMailSenderImpl mailSender;
@Test
public void testSimpleMessage(){
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("第一封测试邮件");
message.setText("邮件测试。。。");
message.setFrom("你的邮箱账号");
message.setTo("发送对象的邮箱账号");
mailSender.send(message);
}
手动创建JavaMailSenderImpl并设置属性:
@Test
public void testSimpleMessage(){
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setUsername("你的邮箱账号");
//网易邮箱授权码
mailSender.setPassword("xxxxxxx");
mailSender.setHost("smtp.163.com");
mailSender.setProtocol("smtp");
//mail.smtp.ssl.enable=true
Properties properties = new Properties();
properties.setProperty("mail.smtp.ssl.enable","true");
mailSender.setJavaMailProperties(properties);
System.out.println(mailSender);
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("第一封测试邮件");
message.setText("邮件测试。。。");
message.setFrom("你的邮箱账号");
message.setTo("发送对象的邮箱账号");
mailSender.send(message);
}
【3】复杂消息发送示例
① 发送邮件附带图片附件
测试代码如下:
@Test
public void testMimeMessage() throws Exception{
// 创建复杂消息
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
helper.setSubject("第二封邮件");
helper.setText("<b style='color:red'>邮件测试....</b>",true);
helper.setFrom("你的邮箱账号");
helper.setTo("发送对象的邮箱账号");
helper.addAttachment("1.jpg",new File("C:\\Users\\12746\\Pictures\\22\\1.jpg"));
helper.addAttachment("2.jpg",new File("C:\\Users\\12746\\Pictures\\22\\2.jpg"));
mailSender.send(mimeMessage);
}
测试结果如下图:
② 发送HTML片段
HTML片段如下:
<dd书城>---用户激活---",
"<html><body><a href='http://"+ip+"/user/active?activeCode=" + userNotActive.getCode() + "'>亲爱的" + user.getUsername() +
",请您点击此链接前往激活</a></body></html>
测试代码如下:
@Override
@Async//异步发邮件
public void sendHtmlMail(String to, String subject, String content) throws Exception {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true);
mimeMessageHelper.setFrom(from);
mimeMessageHelper.setTo(to);
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(content,true);
try {
mailSender.send(message);
logger.info("邮件已经发送。");
} catch (Exception e) {
logger.error("发送邮件时发生异常!", e);
throw new BSException("发送邮件时发生异常!");
}
}