java发送邮件(spring + velocity)

本文介绍如何在spring框架发送邮件,使用vm模板输出邮件内容。其实调用现成的接口就OK了。这东西有固定的套路,可复用性还是蛮高的,记录下来也方便以后copy~~

前言

先说一下这个demo,这里我的邮件内容是一个表格,当用户在前台插入一条或多条记录时会把记录内容以邮件的形式发送过来,提醒及时处理。

邮件内容是以velocity模板(一种html模板)构造的,内容很简单,就是一个table。

后端是spring框架,邮件服务是一个service类。

收件人、发件人等我是以文件的形式放在resource目录下配置,比起在代码中写死更容易扩展。

配置

mail-context.xml

resource目录下,新建mail-context.xml,文件名无所谓。内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">


<!--①邮件服务器-->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="protocol" value="****" />
<property name="host" value="****" />
<property name="port" value="****" />
<property name="username" value="****" />
<property name="password" value="****" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.connectiontimeout">30000</prop>
<prop key="mail.smtp.timeout">30000</prop>
<prop key="mail.smtp.sendpartial">true</prop>
</props>
</property>
</bean>

<bean id="mailVelocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<props>
<prop key="resource.loader">class</prop>
<prop key="class.resource.loader.class">org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader</prop>
<prop key="velocimacro.library"/>
<prop key="input.encoding">UTF-8</prop>
<prop key="output.encoding">UTF-8</prop>
<prop key="default.contentType">text/html; charset=UTF-8</prop>
</props>
</property>
</bean>

</beans>

注意协议、服务器、端口、用户名、密码,我都用*代替了,根据自己情况替换相应值。

然后别忘了在spring的基础配置xml(web.xml中context-param所引用的xml)中,导入该xml。

1
<import resource="mail-context.xml"/>

mail.properties

收件人、发件人和一些其它配置都可以放在该文件中,由service类读取。文件名随便取。如下,我这里配置了发件人、收件人以及多个收件人的情况,该文件同样放在resource目录下。

1
2
3
mail.from=***
mail.to=***
mail.to.many=***,***,***

星号用相应的邮箱地址代替,mail.to.many可配置任意多个邮箱,逗号分割

前端

因为我需要输出表格,所以用到前端html的一些样式,采用了vm模板,方便传值。当然你也可以在后端service里写一堆html标签,你不嫌乱的话……如果你只是输出文字,不需要样式结构,这一步就可以跳过了。

在resource目录下,新建template目录,该目录下新建mail.vm文件。

我的文件内容如下,你可以根据要输出的内容自己定制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.css">
</head>
<body>

<div class="content-fluid">
<div class="table-responsive">
<table class="table" style="margin: 10px auto">
<thead>
<tr>
<th>***</th>
<th>***</th>
<th>***</th>
<th>***</th>
<th>***</th>
<th>***</th>
<th>***</th>
<th>***</th>
<th>***</th>
<th>***</th>
</tr>
</thead>
<tbody>
#foreach(${incidentModel} in ${incidentModels})
<tr>
<td>${incidentModel.incidentId}</td>
<td>${incidentModel.subject}</td>
<td>${incidentModel.priority}</td>
<td>${incidentModel.incidentBegin}</td>
<td>${incidentModel.incidentEnd}</td>
<td>${incidentModel.description}</td>
<td>${incidentModel.reason}</td>
<td>${incidentModel.impactBusiness}</td>
<td>${incidentModel.responsibleTeam}</td>
<td>${incidentModel.responsibleRatio}</td>
</tr>
#end
</tbody>
</table>
</div>
</div>

</body>
</html>

其中foreach是vm的语法,可以自行百度,incidentModels是后端传来的值,这里是个List类型。

MailService类

这个类也很简单,就是利用mail接口发送邮件,还有读取mail.properties配置发件人、收件人等.

我这里主题是字符串常量写死了,你也可以配置在文件里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import com.google.common.collect.Maps;
import com.xxx.model.Email;
import com.xxx.model.IncidentModel;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.ui.velocity.VelocityEngineUtils;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

@Service
public class MailService {

private static final Logger LOG = LoggerFactory.getLogger(MailService.class);
private static final String SUBJECT = "有新的记录推送,请及时处理";

private static Properties properties = new Properties();

static {
try {
properties.load(MailService.class.getResourceAsStream("/config/mail.properties"));
} catch (IOException e) {
LOG.error("加载mail.properties失败", e);
}
}

private final JavaMailSenderImpl mailSender;
private final VelocityEngine velocityEngine;

@Autowired
public MailService(JavaMailSenderImpl mailSender, VelocityEngine velocityEngine) {
this.mailSender = mailSender;
this.velocityEngine = velocityEngine;
}

public void mailNotification(List<IncidentModel> incidentModels) {

Map<String, Object> velocityMailParameter = Maps.newHashMap();
velocityMailParameter.put("incidentModels", incidentModels);

// velocity模板生成html内容
String content = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "template/mail.vm", velocityMailParameter);
String fromAddress = properties.getProperty("mail.from");
String[] toAddress = properties.getProperty("mail.to.many").split(",");
Email email = new Email();
email.setFromAddress(fromAddress);
email.setToAddress(toAddress);
email.setSubject(SUBJECT);
email.setContent(content);

try {
sendMail(email);
} catch (MessagingException e) {
LOG.error("发送邮件过程失败", e);
} catch (IOException e) {
LOG.error("发送邮件失败", e);
}
}

private void sendMail(Email email) throws MessagingException, IOException {

MimeMessage mime = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mime, true, "utf-8");
helper.setFrom(email.getFromAddress());// 发件人
helper.setTo(email.getToAddress());// 收件人
helper.setReplyTo(email.getFromAddress());// 回复到
helper.setSubject(email.getSubject());// 邮件主题
helper.setText(email.getContent(), true);// true表示设定html格式
mailSender.send(mime);

}

}

这样就完事了,以后可以直接拿过来复用,改下收件人、发件人、主题、内容啥的就OK。

坚持原创技术分享,您的支持将鼓励我继续创作!
分享到: