在一些客户响应系统中,面对客户的需求,我们有可能需要通过邮件对客户进行通知或者向客户反馈查询信息。
比如:银行的账单系统,需要对客户的查账请求进行处理,发送账单邮件,此时就能将账单数据写入到HTML文档中,通过邮件发送到客户的邮箱进行回馈;移动运营商的客户响应也包括查询余额、查询套餐等功能,都可以通过邮件订阅。而服务端只需要将模板设定好,将数据嵌套进去,就能针对每个客户发送不同的反馈信息。
所以今天写的示例,就是在Java程序中,发送一个可以设置通知对象和通知内容的HTML邮件。
1.首先我们需要操作HTML文档,在java程序中,操作HTML、XML只要使用Dom4j即可,可以将文档转化成document对象,在程序中进行读写。
2.发送邮件需要用到javamail工具,需要对javamail发送邮件的配置和使用有一定的研究。我在之前写过一个使用构建器配置参数的javamail工具类,就直接拿来用了~
pageTemplet.html
<html>
<head>
<title>通知邮件title>
<meta charset="utf-8"/>
<style type="text/css">
body{
font-size: 10pt;
}
.header,.content,.footer{
width: 600px;
height: 180px;
}
.footer{
text-align: right;
}
#name{
color: grey;
}
#message{
color: grey;
}
style>
head>
<body>
<div class="header">
<img src="http://www.zhku.edu.cn/images/logo.jpg" alt="zhkulogo"/>
div>
<div class="content">
你好,<span id="name">span>同学:<br/><br/>
<div id="message">
<span> span><span id="message">span>
div>
<div class="footer">
校园通知(<span id="time">span>)
div>
div>
body>
html>
MailSender .java
package util;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MailSender {
private final Properties prop = new Properties();
private final Session session;
private final Message msg;
private final Transport transport;
//构建器
public static class Builder{
private final String mailContent;
private final String toAddress;
private String debug = "true";
private String auth = "true";
private String host = "smtp.163.com";
private String protocol = "smtp";
private String subject = "通知邮件";
//发件人地址
private String fromAddress= "[email protected]";
//发件账户密码
private String fromCount = "xxxxx";
private String fromPassword = "xxxxx";
public Builder Debug(String debug) {
this.debug = debug;
return this;
}
public Builder Subject(String subject) {
this.subject = subject;
return this;
}
public Builder Auth(String auth) {
this.auth = auth;
return this;
}
public Builder Host(String host) {
this.host = host;
return this;
}
public Builder FromCount(String fromCount) {
this.fromCount = fromCount;
return this;
}
public Builder FromAddress(String fromAddress) {
this.fromAddress = fromAddress;
return this;
}
public Builder FromPassword(String fromPassword) {
this.fromPassword = fromPassword;
return this;
}
public Builder(String mailContent, String toAddress) {
this.mailContent = mailContent;
this.toAddress = toAddress;
}
public Builder Protocol(String protocol) {
this.protocol = protocol;
return this;
}
public MailSender send() throws Exception{
return new MailSender(this);
}
}
private MailSender(Builder builder) throws Exception{
prop.setProperty("mail.debug", builder.debug);
prop.setProperty("mail.smtp.auth", builder.auth);
prop.setProperty("mail.host", builder.host);
prop.setProperty("mail.transport.protocol",builder.protocol);
session = Session.getInstance(prop);
msg = new MimeMessage(session);
transport = session.getTransport();
msg.setSubject(builder.subject);
msg.setFrom(new InternetAddress(builder.fromAddress,"通知邮件"));
transport.connect(builder.fromCount,builder.fromPassword);
//在这里contentType要设置成text/html,编码格式也要视情况而设定
msg.setContent(builder.mailContent, "text/html;charset=utf-8");
transport.sendMessage(msg, new Address[] {new InternetAddress(builder.toAddress)});
}
}
SendHTMLMail.java
package practice;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Calendar;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
import util.MailSender;
/**
* 类描述:示例如何根据html模板发送html邮件
* @author xiezd
*
*/
public class SendHTMLMail {
@Test
public void send(){
SAXReader reader = new SAXReader();
Document document = null;
try {
//获取模板html文档
document = reader.read(SendHTMLMail.class.getResource("../file/pageTemplet.html").getPath());
Element root = document.getRootElement();
//分别获取id为name、message、time的节点。
Element name = getNodes(root,"id","name");
Element message = getNodes(root,"id","message");
Element time = getNodes(root, "id", "time");
//设置收件人姓名,通知信息、当前时间
Calendar calendar = Calendar.getInstance();
time.setText(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)+"-"+calendar.get(Calendar.DATE));
name.setText("小明");
//随便写的
message.setText("因为您、我有缘,所以才能共结一个圆。为进一步优化教育环境,"
+ "加强家校互动,共同促进学生的成长和进步,本着家校共育的精神,我校决定召开高一家长会,"
+ "希望你在百忙中抽出时间,拨冗光临,对孩子在家和在校的表现与各班主任进行深入的面对面交流,"
+ "针对每个孩子的不同特点,与老师共同商讨教育孩子的策略,最大程度的促进您孩子的进步。");
//保存到临时文件
FileWriter fwriter = new FileWriter("d:/temp.html");
XMLWriter writer = new XMLWriter(fwriter);
writer.write(document);
writer.flush();
//读取临时文件,并把html数据写入到字符串str中,通过邮箱工具发送
FileReader in = new FileReader("d:/temp.html");
char[] buff = new char[1024*10];
in.read(buff);
String str = new String(buff);
System.out.println(str.toString());
new MailSender.Builder(str.toString(),"[email protected]").send();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 方法描述:递归遍历子节点,根据属性名和属性值,找到对应属性名和属性值的那个子孙节点。
* @param node 要进行子节点遍历的节点
* @param attrName 属性名
* @param attrValue 属性值
* @return 返回对应的节点或null
*/
public Element getNodes(Element node, String attrName, String attrValue) {
final List listAttr = node.attributes();// 当前节点的所有属性
for (final Attribute attr : listAttr) {// 遍历当前节点的所有属性
final String name = attr.getName();// 属性名称
final String value = attr.getValue();// 属性的值
System.out.println("属性名称:" + name + "---->属性值:" + value);
if(attrName.equals(name) && attrValue.equals(value)){
return node;
}
}
// 递归遍历当前节点所有的子节点
final List listElement = node.elements();// 所有一级子节点的list
for (Element e : listElement) {// 遍历所有一级子节点
Element temp = getNodes(e,attrName,attrValue);
// 递归
if(temp != null){
return temp;
};
}
return null;
}
}