並不是在研究郵件服務器實現,這兩天學習用Maven,看的《Maven實戰》,裏面用到的郵件的代碼不知咋測試,搜了下本地郵件服務器,參考下面文章,啓動JAMES後,添加用戶,而後就能夠測試書上的代碼了。有個錯誤是由於開着Avast致使的,不清楚爲啥,反正禁用了Avast就經過了。文章寫得比較早,有的代碼用不起來,我作了些許改動。裏面有的須要jar包,可經過Maven依賴導入。JAMES已有3.0版本,因此文章仍彷佛有點過期了,暫時無論。java
用JAMES實現本身的郵件服務器apache
James是一個企業級的郵件服務器,它徹底實現了smtp和pops以及nntp協議。同時,james服務器又是一個郵件應用程序平臺。James的核心是Mailet API,而james服務器是一個mailet的容器。它可讓你很是容易的實現出很強大的郵件應用程序。James開源項目被普遍的應用於與郵件有關的項目中。你能夠經過它來搭建本身的郵件服務器。咱們能夠利用Mailet API編程接口來實現本身所需的業務。James集成了Avalon應用程序框架以及Phoenix Avalon框架容器。Phoenix爲james服務器提供了強大的支持。須要說明的是Avalon開源項目目前已經關閉。編程
我此次使用的安裝包是james 2.3.2你們能夠從這裏下載到。api
如今讓咱們開始咱們激動人心的james之旅。首先咱們將james-binary-2.3.2.zip解壓縮到你的安裝目錄。咱們能夠把這個過程理解爲安裝的過程。我在這裏將它解壓到D:\.這樣咱們的james就安裝好了。目錄爲D:\james-2.3.2。tomcat
在我使用james的時候讓我感受首先理解james的應用程序結構是很重要的。不然你會在使用中感到很困惑。服務器
它的應用程序結構是這樣的:app
James |__ apps |__ bin |__ conf |__ ext |__ lib |__ logs |__ tools
咱們重點介紹一下兩個文件夾bin和apps。框架
bin目錄中的run.bat和run.sh是James的啓動程序。只要記住這個重要文件就能夠。學習
啓動以後控制檯顯示以下:測試
Using PHOENIX_HOME: D:\james-2.3.2 Using PHOENIX_TMPDIR: D:\james-2.3.2\temp Using JAVA_HOME: C:\Program Files\Java\jdk1.7.0_17 Phoenix 4.2 James Mail Server 2.3.2 Remote Manager Service started plain:4555 POP3 Service started plain:110 SMTP Service started plain:25 NNTP Service started plain:119 FetchMail Disabled
Apps目錄下有個james的子目錄這個目錄是它的核心。
james |__ SAR-INF |__ conf |__ logs |__ var |__ mail |__ address-error |__ error |__ indexes |__ outgoing |__ relay-denied |__ spam |__ spool |__ nntp |__ .... |__ users
SAR-INF下有一個config.xml是james中的核心配置文件。
logs包含了與james有關的log。調試全靠它了。
var 包含了一些文件夾經過它們的名字咱們大概也能猜想出它們的用途。
mail 主要用於存儲郵件。nntp主要用於新聞服務器。
users用於存儲全部郵件服務器的用戶。也就是郵件地址前面的東東。如:pig@sina.com的pig就是所謂用戶。
咱們在James上建若干用戶,用來測試收發郵件。固然若是你不用james自己的用戶也能夠。James以telnet的方式提供了接口用來添加用戶。下面我來演示一下。
首先使用telnet來鏈接james的remote manager。
1.telnet localhost 4555 回車 2.而後輸入管理員用戶名和密碼(user/pwd:root/root 是默認設置,這個能夠在config.xml中修改)
JAMES Remote Administration Tool 2.3.2 Please enter your login and password Login id: root Password: root Welcome root. HELP for a list of commands
3.添加用戶
adduser test1 123456 User test1 added adduser test2 123456 User test2 added adduser test3 123456 User test3 added
4.查看添加狀況
listusers Existing accounts 3 user: test1 user: test2
獲得上面的信息說明咱們已經添加成功。
這個類主要用來測試咱們的郵件服務器,能夠不用將其打入包中。
import java.util.Date; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; public class Mail { private String mailServer, from, to, mailSubject, mailContent; private String username, password; private Session mailSession; private Properties prop; private Message message; // Authenticator auth;//認證 public Mail() { // 設置郵件相關 username = "test1"; password = "123456"; mailServer = "localhost"; from = "test1@localhost"; to = "test2@localhost"; mailSubject = "Hello Scientist"; mailContent = "How are you today!"; } public void send() { EmailAuthenticator mailauth = new EmailAuthenticator(username, password); // 設置郵件服務器 prop = new Properties(); prop.put("mail.smtp.auth", "true"); prop.put("mail.smtp.host", mailServer); // 產生新的Session服務 mailSession = mailSession.getDefaultInstance(prop, (Authenticator) mailauth); message = new MimeMessage(mailSession); try { message.setFrom(new InternetAddress(from)); // 設置發件人 message.setRecipient(Message.RecipientType.TO, new InternetAddress( to));// 設置收件人 message.setSubject(mailSubject);// 設置主題 message.setContent(mailContent, "text/plain");// 設置內容 message.setSentDate(new Date());// 設置日期 Transport tran = mailSession.getTransport("smtp"); tran.connect(mailServer, username, password); tran.send(message, message.getAllRecipients()); tran.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Mail mail; mail = new Mail(); System.out.println("sending......"); mail.send(); System.out.println("finished!"); } } class EmailAuthenticator extends Authenticator { private String m_username = null; private String m_userpass = null; void setUsername(String username) { m_username = username; } void setUserpass(String userpass) { m_userpass = userpass; } public EmailAuthenticator(String username, String userpass) { super(); setUsername(username); setUserpass(userpass); } public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(m_username, m_userpass); } }
我先解釋一下大概的流程:當james接收到一個smtp請求時首先會交給matcher來進行一系列過濾動做。而後由matcher交給相應的mailet來進行處理。James就至關於一個matcher和mailet的容器。就像tomcat之於servlet。而mailet和servlet非常類似。
咱們這裏要完成的功能很簡單,就是當james郵件服務器接收到郵件後把發送者和郵件正文打印到控制檯。咱們分析這個需求發現咱們須要寫一個matcher以及一個mailet。matcher用來過濾,而mailet用來將郵件內容打印到控制檯。爲了簡單起見,我此次只是繼承了GenericMailet和GenericRecipientMatcher兩個已經實現的mailet和matcher。具體的Matcher和Mailet的使用我之後會整理成另一篇文章。
package com.zoey.james.mail; import javax.mail.MessagingException; import org.apache.mailet.MailAddress; import org.apache.mailet.base.GenericRecipientMatcher; /** * System jamesstudy Package com.yy.jamesstudy * * @author Yang Yang Created on 2007-9-14下午02:17:07 */ public class BizMatcher extends GenericRecipientMatcher { public boolean matchRecipient(MailAddress recipient) throws MessagingException { // 只接受郵件地址包含鳴人的郵件 if (recipient.getUser().indexOf("test1") != -1) { return true; } return false; } }
GenericRecipientMatcher是一個針對收件人進行過濾的matcher。
import java.io.IOException; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import org.apache.mailet.Mail; import org.apache.mailet.MailAddress; import org.apache.mailet.base.GenericMailet; /** * System jamesstudy Package com.yy.jamesstudy * * @author Yang Yang Created on 2007-9-14下午02:16:31 */ public class BizMaillet extends GenericMailet { public void service(Mail mail) { MailAddress ma = mail.getSender(); System.out.println("sender:" + ma.toInternetAddress().toString()); try { MimeMessage mm = mail.getMessage(); System.out.println("content:" + (String) mm.getContent().toString()); } catch (IOException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } }
GenericMailet是一個mailet的基本實現。
咱們把這兩個java文件的class文件編譯成一個名字爲:jamesstudy.jar的jar文件。
發佈-Matcher和Mailet以及config.xml
1.發佈jar文件
咱們把這個jar文件發佈到D:\james-2.3.2\apps\james\SAR-INF\lib。
注意:若是沒有找到相關目錄,則須要先啓動一遍james,相關的文件夾纔會被建立。還有一點須要特別說明:lib目錄是經過咱們手動建立的。
2.將Matcher和Mailet發佈到config.xml中,config.xml在james-2.3.2\apps\james\SAR-INF\下
1)咱們首先找到以下內容
<mailetpackages> <mailetpackage>org.apache.james.transport.mailets</mailetpackage> <mailetpackage>org.apache.james.transport.mailets.smime</mailetpackage> </mailetpackages> <matcherpackages> <matcherpackage>org.apache.james.transport.matchers</matcherpackage> <matcherpackage>org.apache.james.transport.matchers.smime</matcherpackage> </matcherpackages>
2)加入包聲明
<mailetpackages> <mailetpackage>com.yy.jamesstudy</mailetpackage> <mailetpackage>org.apache.james.transport.mailets</mailetpackage> <mailetpackage>org.apache.james.transport.mailets.smime</mailetpackage> </mailetpackage> <matcherpackages> <matcherpackage>com.yy.jamesstudy</mailetpackage> <matcherpackage>org.apache.james.transport.matchers</mailetpackage> <matcherpackage>org.apache.james.transport.matchers.smime</mailetpackage> </mailetpackage>
3)加入Matcher和Mailet的關聯關係
找到<processor name="root"></processor>
元素在它的下面加入
<mailet match="BizMatcher" class="BizMaillet"/>
Mailet元素表明了一個matcher和一個mailet的組合。Match屬性:是指matcher的類名。而class屬性:是指mailet的類名。
最後別忘了,保存退出。而且從新啓動james服務器。
測試- 驗證咱們的mail應用程序
咱們主要經過mail類來測試咱們的應用。還記得咱們剛纔寫的那個mail類嗎?!在那個類中咱們初始化了相關的信息.
username = "test1"; password = "123456"; mailServer = "localhost"; From = "test1@localhost"; To = "test2@localhost"; mailSubject = "Hello Scientist"; MailContent = "How are you today!";
發件人是test1,收件人是test2.
這兩個用戶咱們在前面都已經建立完畢。咱們用他們來測試james的郵件收發以及mailet api的應用。
根據需求假設咱們發給james服務器(這裏是james的默認配置:localhost)的郵件的收件人是鳴人。那麼咱們就能經過matcher監測到這封郵件,而且調用相應的mailet來進行處理。由mailet打印出相應的郵件發送者和正文。運行Mail類後獲得:
Using PHOENIX_HOME: D:\james-2.3.2 Using PHOENIX_TMPDIR: D:\james-2.3.2\temp Using JAVA_HOME: C:\Program Files\Java\jdk1.7.0_17 Phoenix 4.2 James Mail Server 2.3.2 Remote Manager Service started plain:4555 POP3 Service started plain:110 SMTP Service started plain:25 NNTP Service started plain:119 FetchMail Disabled sender:kakaxi@localhost content:How are you today!
最終咱們看到發送者和正文的信息。That’s all ! 大功告成。
其實james的功能是很是很是強大的,尤爲是它的Mailet API可以幫助咱們完成不少與郵件有關的工做如過濾垃圾郵件。用它咱們甚至能夠搭建咱們本身的企業郵件服務器。咱們最近的項目中就使用到了。咱們經過james接收到的郵件,而後用matcher找到咱們想要處理的郵件,而後經過mailet作一些業務上的處理。這篇文章涵蓋的面很小。若是你們有興趣能夠研究一下james項目。Config.xml其實是最重要的文件,若是你把它研究透徹了那麼就算把Mailet API研究透了。之後我可能會寫一篇相關的文章,在這就很少說了。但願這篇文章可以對你們有所啓發!有所幫助!祝你們工做順利!