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均接收多个接收者,用","隔开,比如 [email protected],[email protected] * */@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("[email protected]", "test", "[email protected]", "Hello!"); MailEntity entity = new MailEntity(); entity.setTarget("[email protected]"); entity.putData("name", "szy.foggy"); entity.putData("array", new String[]{"A","B","C","D","E"}); mailService.sendRemindMail(entity); }