Java发送邮件(二)之Spring
前言
之前的博客《Java发送邮件(一)之JavaMail》中介绍了如何利用原生JavaMail发送邮件,但是操作上略显复杂,这个时候我们的万金油框架Spring就来了,Spring在JavaMail的基础上做了一些封装,在使用上会比原生更简易,且不容易出错,我们来看看吧。本次我们测试使用的是SpringBoot,JavaMail的版本依然是1.4.7。
一、引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
二、配置参数
2.1 application.properties
#服务器主机名
mail.smtp.host=smtp.qq.com
mail.smtp.port=25
#你的邮箱地址
mail.smtp.username=fajianren@qq.com
#你的授权码
mail.smtp.password=wmz******jf
#编码格式
mail.smtp.defaultEncoding=utf-8
#是否进行用户名密码校验
mail.smtp.auth=true
#设置超时时间
mail.smtp.timeout=20000
2.2 自动装配参数
@Component
@ConfigurationProperties(prefix = "mail.smtp")
public class MailConfigurationProperties {
private String host;
private int port;
private String username;
private String password;
private String auth;
private String defaultEncoding;
private Integer timeout;
// 省略getter setter
}
@Configuration
public class MailConfigurations {
@Autowired
private MailConfigurationProperties properties;
@Bean
public JavaMailSender javaMailSender(){
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setDefaultEncoding(properties.getDefaultEncoding());
Properties props = new Properties();
props.put("mail.transport.protocol","smtp");
props.put("mail.debug", "true");
props.put("mail.smtp.auth",properties.getAuth());
props.put("mail.smtp.timeout",properties.getTimeout());
javaMailSender.setJavaMailProperties(props);
javaMailSender.setHost(properties.getHost());
javaMailSender.setUsername(properties.getUsername());
javaMailSender.setPassword(properties.getPassword());
javaMailSender.setPort(properties.getPort());
return javaMailSender;
}
}
三、邮件发送
3.1 发送demo
@SpringBootTest
class SpringMailDemoApplicationTests {
@Autowired
JavaMailSender javaMailSender;
@Autowired
FreeMarkerConfigurationFactory freeMarkerConfigurationFactoryBean;
@Test
void contextLoads() throws MessagingException {
MimeMessage msg = javaMailSender.createMimeMessage();
// MimeMessageHelper是组装MimeMessage的,比原生的MimeMessage方法多一些合法性的校验工作
MimeMessageHelper helper = new MimeMessageHelper(msg,"UTF-8");
// 设置发件人
String from = "fajianren@qq.com";
helper.setFrom(from);
// 设置收件人
String recipient = "shoujianren@qq.com";
helper.setTo(recipient);
// 设置抄送人,
helper.setCc(recipient);
// 如果是密送请使用setBcc
// helper.setBcc(recipient);
// 设置邮件主题,如果主题中存在中文,要使用支持的字符集
helper.setSubject("JavaMail邮件测试");
// 设置发送时间,这个时间可以随意设置,用于显示发送时间
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH,-1);
Date date = calendar.getTime();
helper.setSentDate(date);
// 设置发送正文,setText(String msg, boolean isHtml)
helper.setText("Hello JavaMail In Spring",false);
// 发送邮件
javaMailSender.send(msg);
}
}
3.2 关于MimeMessageHelper
我们对比看原生JavaMail,Spring多出来一个MimeMessageHelper,这个类从名字上来看就是帮助构建MimeMessage的,如果感兴趣的话,我们随便看一个方法源码,如setFrom方法,
public void setFrom(String from) throws MessagingException {
Assert.notNull(from, "From address must not be null");
this.setFrom(this.parseAddress(from));
}
public void setFrom(InternetAddress from) throws MessagingException {
Assert.notNull(from, "From address must not be null");
this.validateAddress(from);
this.mimeMessage.setFrom(from);
}
我们会发现这个方法在原来MimeMessage的相应方法前做了一些校验,便于我们正确的设置参数,所以是非常好用的。
四、进阶用法
4.1 如何发送高级格式的邮件呢,如html?
我们在上文中看到了MimeMessageHelper的helper.setText(“Hello JavaMail In Spring”,false); 其中第二个参数isHtml就是代表发送的邮件内容格式是否是html了,当为true的时候就是html解析了。
4.2 如何发送模板动态内容解析的邮件呢?
动态内容邮件,我们只需要在邮件发送前,加入邮件内容的动态解析过程即可,可以利用一些模版引擎来实现,如freeMarker。当然也可以自己手动定义模版,并利用字符串函数取代相应的占位符,然后获取到最终的html文本,发送即可。
我们简单的以freeMarker举例来看:
首先引入freeMarker的依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
使用SpringBoot的时候,freemarker的引入可以不用写版本号,若版本号与springboot不匹配可能会出现启动异常: Unknown FreeMarker configuration setting: “recognize_standard_file_extension”
通过freemarker渲染邮件模版
邮件模版:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring JavaMail</title>
</head>
<body>
<h1>你好, ${username}</h1>
</body>
</html>
模版渲染:
private String getEmailTempate() throws IOException, TemplateException {
Configuration cfg = new Configuration(Configuration.getVersion());
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setClassForTemplateLoading(this.getClass(), "/templates");
cfg.setLogTemplateExceptions(false);
cfg.setWrapUncheckedExceptions(true);
Template temp = cfg.getTemplate( "mail.ftl");
Map<String,Object> paramsMap = new HashMap<>();
paramsMap.put("username","JavaMail");
String html = FreeMarkerTemplateUtils.processTemplateIntoString(temp, paramsMap);
return html;
}
邮件发送时,只需要改动上文简单示例中最后的发送邮件的代码
helper.setText(getEmailTempate(),true);