本文档分三个部分,第一部分简要简单介绍了JavaMail,第二部分用一个完整的JavaMail的实例(API)详解javamail,
最后写测试javamail API的例子和两个使用javamail中的重要技术,一个是介绍如何用velocity构建javamail的模板,
一个是如何读取properties文件。
javamail 简介:
JavaMail是Sun发布的用来处理email的API。它能够方便地执行一些经常使用的邮件传输。
虽然JavaMail是Sun的API之一,但它目前尚未被加在标准的java开发工具包中
(Java Development Kit),这就意味着你在使用前必须另外下载JavaMail文件。除此之外,
你还须要有Sun的JavaBeans Activation Framework (JAF)。JavaBeans Activation Framework
的运行很复杂,在这里简单的说就是JavaMail的运行必须得依赖于它的支持。在Windows 2000下
使用须要指定这些文件的路径,在其它的操做系统上也相似。
Java Mail API是Java对电子邮件处理的延伸,它提供和通信协定无关的 Java解决方案,
能够处理各类email格式,包括IMAP、POP、SMTP,以及MI ME,和其余和Internet相关的讯息通信协
javamail API实例:
在写实例前 咱们须要载两个jar包,一个是javamail.jar和activation.jar,这里有个要说明下,
若是你用的是jdk1.6的版本,那么能够不用activation.jar,若是是jdk1.6一下的版本要用activation.jar,
由于jdk1.6集成了activation.jar。 你能够到 http://java.sun.com/products/javamail/downloads/index.html 去下载
说了那么多 下面就是咱们的具体javamail的代码了 SendMail.java
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
class SendMail {
private MimeMessage mimeMsg; //MIME邮件对象
private Session session; //邮件会话对象
private Properties props; //系统属性
private boolean needAuth = false; //smtp是否须要认证
private String username = ""; //smtp认证用户名和密码
private String password = "";
private String agentIp = "";
private String agentPort = "";
private Multipart mp;
private static final String CHAR_SET = "UTF-8"; //Multipart对象,邮件内容,标题,附件等内容均添加到其中后再生成MimeMessage对象
public SendMail() {
}
/**
* this construct has no agent
*
* @param smtp
*/
public SendMail(String smtp) {
setSmtpHost(smtp);
createMimeMessage();
}
/**
* this construct has agent
*
* @param smtp
* @param agentIp
* @param agentPort
*/
public SendMail(String smtp, String agentIp, String agentPort) {
this.agentIp = agentIp;
this.agentPort = agentPort;
setSmtpHost(smtp);
createMimeMessage();
}
/**
* it is set the hostName
*
* @param hostName String
*/
public void setSmtpHost(String hostName) {
if (props == null)
props = System.getProperties(); //得到系统属性对象
props.put("mail.smtp.host", hostName); //设置SMTP主机
if (null != this.agentIp && this.agentIp.length() != 0 && !this.agentIp.equals("0")) {
props.put("http.proxyHost", this.agentIp);
}
if (null != this.agentPort && this.agentPort.length() != 0 && !this.agentPort.equals("0")) {
props.put("http.proxyPort", this.agentPort);
}
}
/**
* creete MIME mail object
*
* @return boolean
*/
public boolean createMimeMessage() {
try {
session = Session.getDefaultInstance(props, null); //得到邮件会话对象
}
catch (Exception e) {
return false;
}
try {
mimeMsg = new MimeMessage(session); //建立MIME邮件对象
mp = new MimeMultipart();
return true;
}
catch (Exception e) {
System.err.println("create MIME mail object failure" + e);
return false;
}
}
/**
* set identity of tsmtp validation
*
* @param needAuth boolean
*/
public void setNeedAuth(boolean needAuth) {
if (props == null) props = System.getProperties();
if (needAuth) {
props.put("mail.smtp.auth", "true");
} else {
props.put("mail.smtp.auth", "false");
}
}
/**
* set user name and password
*
* @param name boolean
* @param pass boolean
*/
public void setNamePass(String name, String pass) {
username = name;
password = pass;
}
/**
* set subject of mail
*
* @param subject
* @return boolean
*/
public boolean setSubject(String subject) {
try {
mimeMsg.setSubject(subject);
return true;
}
catch (Exception e) {
System.err.println("set mail subject is error " + e);
return false;
}
}
/**
* set the content of mail,the charset of content shoule be UTF-8
*
* @param body
* @return boolean
*/
public boolean setBody(String body) {
try {
BodyPart bp = new MimeBodyPart();
bp.setContent("" + body, "text/html;charset=" + CHAR_SET);
mp.addBodyPart(bp);
return true;
}
catch (Exception e) {
System.err.println("set mail body is error" + e);
return false;
}
}
/**
* add the attachments, "filePath" should be real local path of a file
*
* @param filePath
* @return boolean
*/
public boolean addFileAffix(String filePath) {
try {
BodyPart bp = new MimeBodyPart();
FileDataSource fileds = new FileDataSource(filePath);
bp.setDataHandler(new DataHandler(fileds));
bp.setFileName(fileds.getName());
mp.addBodyPart(bp);
return true;
}
catch (Exception e) {
System.err.println("Affix" + filePath + "accour error" + e);
return false;
}
}
/**
* set the from of mail
*
* @param from
* @return boolean
*/
public boolean setFrom(String from) {
try {
mimeMsg.setFrom(new InternetAddress(from));
return true;
}
catch (Exception e) {
System.out.println("set sender is error" + e);
return false;
}
}
/**
* set the send to of mail
*
* @param to
* @return boolean
*/
public boolean setTo(String to) {
if (to == null) return false;
try {
mimeMsg.setRecipients(Message.RecipientType.TO, (Address[]) InternetAddress.parse(to));
return true;
}
catch (Exception e) {
System.out.println("reciever's address is error" + e);
return false;
}
}
/**
* set the copy to of mail
*
* @param copyto
* @return boolean
*/
public boolean setCopyTo(String copyto) {
if (copyto == null) return false;
try {
mimeMsg.setRecipients(Message.RecipientType.CC, (Address[]) InternetAddress.parse(copyto));
return true;
}
catch (Exception e) {
return false;
}
}
/**
* set the bcc of mail
*
* @param bccto
* @return boolean
*/
public boolean setBccTo(String bccto) {
if (bccto == null) return false;
try {
mimeMsg.setRecipients(Message.RecipientType.BCC, (Address[]) InternetAddress.parse(bccto));
return true;
}
catch (Exception e) {
return false;
}
}
/**
* put the mail send out
*
* @return boolean
*/
public boolean sendout() {
try {
mimeMsg.setContent(mp);
mimeMsg.saveChanges();
Session mailSession = Session.getInstance(props, null);
Transport transport = mailSession.getTransport("smtp");
transport.connect((String) props.get("mail.smtp.host"), username, password);
transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
transport.close();
return true;
}
catch (Exception e) {
System.err.println("send fail\r\n");
System.err.println(e + "\r\n");
return false;
}
}
那么咱们的API就写完了,下面是几点要重要说明的
1.必定是建立Session。
若是,你是发送邮件那么 接下来你须要建立你要发送的邮件,也就是一个 message对象。
如今的message对象好像一张白纸,如今就须要咱们来添加内容啦message.setContent()能够帮你搞定。
而后咱们须要写“信封” message.setFrom(); message.addRecipient();...
哈哈,都搞定了,而后就能够寄出去了
Transport transport = session.getTransport("smtp");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
好了,邮件发送完成了:),嘻嘻固然,这里有些过于乐观了,在发送的过程当中咱们还有遇到其它一些问题,
好比,认证,地址等。下面就JavaMail几个重要的类进行一下介绍
首先是session类:
Session 定义了一个基本的邮件会话,任何工做都是基于这个Session的。Session 对象须要一个
java.util.Properties 对象来获得相似 邮件服务器,用户名,密码这样的信息。
Session 的构造函数是私有的,你能够经过 getDefaultInstance() 方法来取得一个单一的能够被共享的默认session 如:
Properties props = new Properties();
// 填写一些信息
Session session = Session.getDefaultInstance(props,null);
或者,你可使用 getInstance() 方法来建立一个惟一的 session如:
Properties props = new Properties();
// 填写一些信息
Session session = Session.getInstance(props,null);
在这两种方法中 其中的 null 参数是一个 Authenticator 对象,在这里没有被使用的,因此就是null
在大多数案例中,使用一个共享session 已经作够了。
Message类
一 旦你建立了Session对象,那么下面要作的就是建立 message 来发送。Message 是一个抽象类,在大部分应用中你可使用它的子类 javax.mail.internet.MimeMessage 。MimeMessage 是一个理解在不一样RFCs中定义的MIME类型以及headers的e-mail message 。 Message headers 必须使用 US-ASCII 字符集。
能够用以下的方法建立一个 Message
MimeMessage message = new MimeMessage(session);
咱们注意到,这里须要用session对象做为构造函数的参数。固然,还有其它的构造函数,好比从用RFC822格式化过的输入流来建立message。
一旦你获得了 message ,你就能够来设置它的各个部分(parts)。设置内容(content)的基本的机制是使用setContent() 方法。
message.setContent("Email Content. ","text/plain");
若是,你可以明确你的使用MimeMessage来建立message 而且只是使用普通的文本(plain text) 那么你也可使用 setText() 方法,setTest()方法只须要设置具体的内容,它默认的MIME类型是 text/plain
message.setText("Email Content. ");
对于普通文本类型的邮件,有一种机制是首选( message.setText("Email Content. "))的设置内容的方法。若是要建立其它类型的message ,好比 HTML类型的message 那么仍是须要使用前者 ( message.setContent("Email Content. ","text/html"); )
设置主题(subject ),使用setSubject() 方法
message.setSubject(" Subject ");
Address 类
当 你已经建立了Session 以及 Message,而且已经为message 填充了内容,那么接下来要作的就是给你的邮件添加一个地址(Address)。 就像Message同样,Address也是一个抽象类,咱们可使用它 的一个子类javax.mail.internet.InternetAddress 。
建立一个地址很是简单
Address address = new InternetAddress("suixin@asiainfo.com");
若是,你但愿在出现邮件地址的地方出现一个名称,那么你只须要再多传递一个参数。
Address address = new InternetAddress("suixin@asiainfo.com","Steve");
你须要为 message 的from以及 to 字段建立address对象。为了识别发送者,你须要使用setFrom() 和 setReplyTo() 方法。
messge.setFrom(address);
若是你的message 须要显示多个 from 地址,可使用 addFrom() 方法
Address address[] = {....};
message.addFrom(address);
为了辨识message 的收件人,你须要使用 setRecipient() 方法。这个方法除了address参数以外,还须要一个Message.RecipientType 。
message.addRecipient(type,address);
Message.RecipientType有几个预先定义好的类型
Message.RecipientType.TO 收件人
Message.RecipientType.CC 抄送
Message.RecipientType.BCC 暗送
若是你的一封邮件,须要发送给你的老师,并还要给你的几个同窗,那么你能够这样
Address toAddress = new InternetAddress("teacher@17288.com");
Address[] ccAddress = {new InternetAddress("schoolmate1@17288.com"),new InternetAddress("schoolmate2@17288.com")};
message.addRecipient(Message.RecipientType.To, toAddress);
message.addRecipient(Message.RecipientType.CC, ccAddress);
JavaMail 没有提供电子邮件地址有效性的检测。这些超越了JavaMail API的范围。
Authenticator 类
经过Authenticator设置用户名、密码,来访问受保护的资源,这里的资源通常指的是邮件服务器。
Authenticator也是一个抽象类,你须要本身编写子类已备应用。你须要实现getPasswordAuthentication()方法,并返 回一个PasswordAuthentication实例。你必须在 session被建立时, 注册你的 Authenticator。这样,当须要进行认证是,你的Authenticator就能够被获得。
Properties props = new Properties();
//设置属性
Authenticator auth = new YourAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
Transport 类:
发送消息最后的一步就是使用Transport类,你能够经过两种方法来进行发送。
Transport 是一个抽象类,你能够调用它静态的send() 方法来发送
Transport.send(message);
或者,你能够为你使用的协议从session中取得一个指定的实例,
Transport transport = session.getTransport("smtp");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
下面咱们写一个测试类,来测试咱们上面的方法
TestSendMail.java
import java.util.Properties;
import java.io.InputStream;
/**
*
*To test send mail with tamplate
*/
public class TestSendMail {
public static void main(String[] args) throws Exception {
Properties pro = new Properties();
InputStream is = TestSendMail.class.getClassLoader().getResourceAsStream("mail.properties");
pro.load(is);
SendMail themail = new SendMail(pro.getProperty("mail.smtp"), pro.getProperty("mail.agentIp"), pro.getProperty("mail.agentPort"));
themail.setNeedAuth(true);
themail.setNamePass(pro.getProperty("mail.name"), pro.getProperty("mail.password"));
if(null != pro.getProperty("mail.subject").toString() && pro.getProperty("mail.subject").toString() != ""){
themail.setSubject(pro.getProperty("mail.subject").toString());
}
if(null != pro.getProperty("mail.content").toString() && pro.getProperty("mail.content").toString() != ""){
themail.setBody(pro.getProperty("mail.content"));
}
if(null != pro.getProperty("mail.from").toString() && pro.getProperty("mail.from").toString() != ""){
themail.setFrom(pro.getProperty("mail.from"));
}
if(null != pro.getProperty("mail.to").toString() && pro.getProperty("mail.to").toString() != ""){
themail.setTo(pro.getProperty("mail.to"));
}
if(null != pro.getProperty("mail.cc").toString() && pro.getProperty("mail.cc").toString() != ""){
themail.setCopyTo(pro.getProperty("mail.cc").toString());
}
if(null != pro.getProperty("mail.bcc").toString() && pro.getProperty("mail.bcc").toString() != ""){
themail.setBccTo(pro.getProperty("mail.bcc").toString());
}
if(null != pro.getProperty("mail.affixFile")){
themail.addFileAffix(pro.getProperty("mail.affixFile"));
}
themail.sendout();
}
}
注意为了方便咱们把数据都放在一个perproties文件里的,mail.properties这个文件你能够放在任意编译路径下,均可以读到
下面是perproties的内容
mail.smtp = mail.google.com //mail的服务
mail.name = servicetest //邮件的用户名
mail.password = testservice //邮件的密码
mail.agentIp = 10.0.1.8 //代理服务器的Ip
mail.agentPort = 8080 //代理服务器的端口号
mail.from = timoth.wang@dextrys.com // 邮件发送者
mail.to = timoth.wang@dextrys.com // 邮件接收者
mail.cc = andy.zhao@dextrys.com ,lexy.chen@dextrys.com , wg1191@163.com //抄送
mail.bcc = steven.lv@dextrys.com //暗送
mail.subject = this is the subject //主题
mail.affixFile = D:\\wg\\test.css //附件的路径和文件名
mail.content = <a href=http://www.google.com>google</a> //邮件内容
下面将介绍怎样用邮件模板发邮件
咱们用velocity这个优秀的框架来实现咱们的mail模板
下面咱们对velocity 作个简单的认识
Velocity是一个基于java的模板引擎(template engine)。它容许任何人仅仅简单的使用模板语言
(template language)来引用由java代码定义的对象。
当Velocity应用于web开发时,界面设计人员能够和java程序开发人员同步开发一个遵循MVC架构的web站点,
也就是说,页面设计人员能够只关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。
Velocity将java代码从web页面中分离出来,这样为web站点的长期维护提供了便利,同时也为咱们在JSP和PHP之
外又提供了一种可选的方案。
想了解更多,建议去googl一下,由于咱们的主要目的是javamail
那好,咱们就开始咱们的javamail模板之旅吧
首先咱们要下载一个velocity的Jar包才能支持velocity框架 你们能够到这里下 http://velocity.apache.org/download.cgi
建议下1.5版本的
OK ,那么既然是模板咱们就先设计一下咱们的邮件模板吧,velocity因此的模板是一.vm做为后缀名的 因此咱们的mailTemplate.vm
就是咱们的模板文件吧 下面是内容:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>vehicle ceo</title>
</head>
<body >
Hi $to
Welcome to $site
$content
$test
from $from
<body >
</html>
你能够在里面任意设计 若是是变量 那么用$+变量名 这个能够经过后台传进来实现动态交互。
摸版咱们已经设计好了 那么下面咱们来写一个用摸版的方法吧
其实就一个方法而已 , 你能够把这个方法加在前面的SendMial.java类里
/**
* get mail content with template. the keys in the map should relative to the variable that define in the
* body of vm file
*
* @param templateName this is a vm file , the template style in it
* @param map the map you can set the variable in it according you need
* return StringWriter the mail body in it
*/
public String getMailContentWithTemplate(String templateName, Map map) throws Exception {
VelocityEngine ve = new VelocityEngine();
ve.setProperty("file.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
/* next, get the Template */
Template t = ve.getTemplate(templateName, "utf-8");
/* create a context and add data */
VelocityContext context = new VelocityContext();
Iterator keys = map.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next().toString();
context.put(key, map.get(key));
}
StringWriter writer = new StringWriter();
t.merge(context, writer);
return writer.toString();
}
这个方法的两个参数比较重要 templateName 是.vm文件的名字,map这是用户能够自定义的,要注意map里的key要和.vm文件里的变量相对应
具体看下面的测试类
那么下面就是一个对发邮件模板的测试啦 TestTamplate.java
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.io.InputStream;
import java.io.StringWriter;
/**
* To test send mail with tamplate
*/
public class TestTamplate {
public static void main(String args[]) throws Exception {
Properties pro = new Properties();
InputStream is = TestTamplate.class.getClassLoader().getResourceAsStream("mail.properties");
pro.load(is);
SendMail themail = new SendMail(pro.getProperty("mail.smtp"), pro.getProperty("mail.agentIp"), pro.getProperty("mail.agentPort"));
Map map = new HashMap();
map.put("to", "andy.zhao@suzsoft.com");
map.put("site", "vehicle CEO");
map.put("test", "this is a test,中文");
map.put("content", "<a href=\"http://www.google.cn\">aaa</a>");
map.put("from", "eric");
String writer = themail.getMailContentWithTemplate(("mailTemplate.vm"), map);
themail.setNeedAuth(true);
themail.setNamePass(pro.getProperty("mail.name"), pro.getProperty("mail.password"));
themail.setTo(pro.getProperty("mail.to").toString());
if (null != pro.getProperty("mail.cc").toString() && pro.getProperty("mail.cc").toString() != "") {
themail.setCopyTo(pro.getProperty("mail.cc").toString());
}
if (null != pro.getProperty("mail.bcc").toString() && pro.getProperty("mail.bcc").toString() != "") {
themail.setBccTo(pro.getProperty("mail.bcc").toString());
}
if (null != pro.getProperty("mail.subject").toString() && pro.getProperty("mail.subject").toString() != "") {
themail.setSubject(pro.getProperty("mail.subject").toString());
}
themail.setBody(writer);
if (null != pro.getProperty("mail.from") && pro.getProperty("mail.from") != "") {
themail.setFrom(pro.getProperty("mail.from"));
}
if (null != pro.getProperty("mail.affixFile")) {
themail.addFileAffix(pro.getProperty("mail.affixFile"));
}
themail.sendout();
}
}
css