javamail 詳細實現(轉發)

本文檔分三個部分,第一部分簡要簡單介紹了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

相關文章
相關標籤/搜索