package net.devkit.core.mail;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
/**
* 邮件抽象,表示一个具体的邮件内容
*/
public class MailEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1691074179432092417L;
private int id; // id
private Date sendDate; //发送时间
private String target;//发送目的地
private HashMap<String, Object> data = new HashMap<String, Object>(5); //为了提供邮件发送时的模板设置,从context格式化过来的map
public MailEntity() {
}
public HashMap<String, Object> getData() {
return data;
}
public void putData(String key,Object value){
data.put(key, value);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public Date getSendDate() {
return sendDate;
}
public void setSendDate(Date sendDate) {
this.sendDate = sendDate;
}
}
package net.devkit.core.mail;
import org.apache.commons.lang.StringUtils;
/**
* 邮件模板的定义,一封邮件可以有多个模板
*
* @author Atomic
*/
public class MailTemplateDefinition {
String to; // 收件人
String from; // 发件人地址
String subject; // 邮件标题
String plainTextTemplate; // 纯文本格式的邮件模板
String htmlTemplate; // html格式的邮件模板
/**
* 该封邮件是否拥有html头
*/
public boolean isHtmlMail() {
return StringUtils.isNotBlank(htmlTemplate);
}
/**
* 该封邮件是否拥有富文本头
*/
public boolean isPlainTextMail() {
return StringUtils.isNotBlank(plainTextTemplate);
}
/**
* 是否是两种格式都有的
*/
public boolean isAlternativeMail() {
return isPlainTextMail() && isHtmlMail();
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getPlainTextTemplate() {
return plainTextTemplate;
}
public void setPlainTextTemplate(String plainTextTemplate) {
this.plainTextTemplate = plainTextTemplate;
}
public String getHtmlTemplate() {
return htmlTemplate;
}
public void setHtmlTemplate(String htmlTemplate) {
this.htmlTemplate = htmlTemplate;
}
}
package net.devkit.core.mail;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
/**
* 专业生产模板邮件
*
*/@Service
public class TemplateMailFactory {
//邮件模板们
@Resource(name="templateMailContext")
private Map<String, MailTemplateDefinition> templateMailContext;
public MailTemplateDefinition create(String mailId) {
for (String key : templateMailContext.keySet()) {
System.out.println(key + "[" + templateMailContext.get(key) + "]");
}
if (templateMailContext.containsKey(mailId)) {
return templateMailContext.get(mailId);
}
return null;
}
}
package net.devkit.core.mail;
import java.util.Map;
import javax.annotation.Resource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Service;
import org.springframework.ui.velocity.VelocityEngineUtils;
import org.springframework.util.Assert;
/**
* 模板邮件支持,可以在邮件中直接使用$message之类的velocity标记 注意:to,cc均接收多个接收者,用","隔开,比如 111@111.com,222@222.com
*
*/@Service
public class VelocityMimeMessagePreparator implements MimeMessagePreparator{
@Resource
private VelocityEngine velocityEngine; // 使用velocity
@Resource
private TemplateMailFactory templateMailFactory;// 模板邮件缓存
private String to = "";// 收件人
private String cc = "";// 抄送
private Map<String, Object> dataContext;// 被填充的动态数据
private String mailId;// 邮件id
public void prepare(MimeMessage message) throws Exception {
MailTemplateDefinition definition = templateMailFactory.create(mailId);
Assert.notNull(definition);
// 通用邮件头
message.addFrom(InternetAddress.parse(definition.getFrom()));
message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.addRecipients(Message.RecipientType.CC, InternetAddress.parse(cc));
message.setSubject(definition.getSubject());
MimeMultipart multipart = new MimeMultipart("alternative");
message.setContent(multipart);
// 处理PlainText的邮件,建议使用GBK编码...因为中文版OE不会自动切换编码...
if (definition.isPlainTextMail()) {
BodyPart plainText = new MimeBodyPart();
plainText.setText(VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, definition
.getPlainTextTemplate(), "GBK", dataContext));
multipart.addBodyPart(plainText);
}
// 处理html的邮件,建议使用GBK编码...因为中文版OE不会自动切换编码...
if (definition.isHtmlMail()) {
BodyPart html = new MimeBodyPart();
html.setContent(VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, definition
.getHtmlTemplate(), "UTF-8", dataContext), "text/html;charset=UTF-8");
multipart.addBodyPart(html);
}
}
public String getTo() {
return to;
}
public void setMailId(String mailId) {
this.mailId = mailId;
}
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
public void setTo(String to) {
this.to = to;
}
public void setCc(String cc) {
this.cc = cc;
}
public void setDataContext(Map<String, Object> dataContext) {
this.dataContext = dataContext;
}
public void setTemplateMailFactory(TemplateMailFactory templateMailFactory) {
this.templateMailFactory = templateMailFactory;
}
}
package net.devkit.core.mail;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
/**
* 使用Spring进行封装的Javamail,抽象的邮件服务,默认使用Velocity封装了系统必备的邮件
*
*/@Service
public class MailService {
public static final String MAIL_REMIND = "REMIND";
@Resource
JavaMailSender javaMailSender;// 直接使用Javamail
@Resource
VelocityMimeMessagePreparator mailPreparator;
private Logger logger = Logger.getLogger(this.getClass().getName());
/**
* 发送使用了Velocity做模板的复杂邮件
* @param m 要发送的邮件上下文
*/
public void sendRemindMail(MailEntity m) {
Map<String, Object> dataContext = new HashMap<String, Object>();
dataContext.putAll(m.getData());
dataContext.put("target", m.getTarget());
mailPreparator.setMailId(MAIL_REMIND);
mailPreparator.setDataContext(dataContext);
mailPreparator.setTo(m.getTarget());
javaMailSender.send(mailPreparator);
logger.info(String.format("向%s发送了一封提醒邮件,标题为%s", m.getTarget(), mailPreparator.getTo()));
}
/**
* 发送使用了Velocity做模板的复杂邮件
* @param m 要发送的邮件上下文
* @param mailRemindKey 模板邮件缓存的Key
*/
public void sendRemindMail(MailEntity m,String mailRemindKey){
Map<String, Object> dataContext = new HashMap<String, Object>();
dataContext.putAll(m.getData());
dataContext.put("target", m.getTarget());
mailPreparator.setMailId(mailRemindKey);
mailPreparator.setDataContext(dataContext);
mailPreparator.setTo(m.getTarget());
javaMailSender.send(mailPreparator);
logger.info(String.format("向%s发送了一封提醒邮件,标题为%s", m.getTarget(), mailPreparator.getTo()));
}
public void sendSimpleMailMessage(String to, String subject, String from, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setFrom(from);
message.setText(content);
javaMailSender.send(message);
logger.info("发送了一封邮件<" + to + ">,主题为<" + subject + ">");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 模板邮件缓存 -->
<util:map id="templateMailContext">
<!-- 发送提醒邮件的模板 -->
<entry key="REMIND">
<bean class="net.devkit.core.mail.MailTemplateDefinition">
<property name="from" value="${smtp.username}" />
<property name="subject" value="您有新的提醒" />
<property name="htmlTemplate" value="mail/test-html-template.html" />
</bean>
</entry>
<entry key="REGISTER-SUCCESS">
<bean class="net.devkit.core.mail.MailTemplateDefinition">
<property name="from" value="${smtp.username}" />
<property name="subject" value="【注册成功】会员注册成功通知" />
<property name="htmlTemplate" value="mail/register-success.html" />
</bean>
</entry>
<entry key="RESET-USER-PASSWORD">
<bean class="net.devkit.core.mail.MailTemplateDefinition">
<property name="from" value="${smtp.username}" />
<property name="subject" value="【密码重置】会员密码重置通知" />
<property name="htmlTemplate" value="mail/reset-user-password.html" />
</bean>
</entry>
</util:map>
<!-- 默认用来发送邮件的smtp服务 -->
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${smtp.host}" />
<property name="javaMailProperties">
<props>
<!-- 服务器需要smtp认证 -->
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
<property name="username" value="${smtp.username}" />
<property name="password" value="${smtp.password}" />
</bean>
<bean id="velocityEngine"
class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="resourceLoaderPath" value="/WEB-INF/wwwpages/" />
</bean>
</beans>
/**
* 发送测试邮件
*/
@RequestMapping(value="mail",method=RequestMethod.GET)
public void sendTestmail() {
mailService.sendSimpleMailMessage("szy.foggy@gmail.com", "test", "szy.foggy@qq.com", "Hello!");
MailEntity entity = new MailEntity();
entity.setTarget("szy.foggy@gmail.com");
entity.putData("name", "szy.foggy");
entity.putData("array", new String[]{"A","B","C","D","E"});
mailService.sendRemindMail(entity);
}