歡迎光臨
我們一直在努力

企業級郵件服務器apache james介紹(1)_郵件服務器

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

英文原文:http://www-106.ibm.com/developerworks/java/library/j-james1.html
學習這個開源項目的基礎知識

級別: 中級
Claude Duguay (claude.duguay@verizon.net)
首席架構師, Arcessa, Inc.
6,10, 2003

Java Apache企業級郵件服務器 — 通常被稱為James –是Apache組織構建的一個可移植的,安全的,100% 純 Java 實現的企業級郵件服務器。但James有潛力成為功能更強的應用服務器,這得益于它的組件式體系結構和mailet基礎設施。mailet對e-mail所起的作用與 servlets對Web服務器的作用相似。E-mail 服務器在最終發展成為Internet的DARPA出現的早期就已經很普遍了。但 James 為這個經常被稱為Internet最關鍵的應用提供了新的可能性。
這是探索James的兩篇文章中的第一篇. 這篇文章提供了James的概述和探討它的可能性的指導性方向。在第二篇文章中,我們會實現一個mailet應用程序來管理不能發送(unavailability)的消息。你將會發現,為James寫應用程序簡直簡單的令人難以置信。在這個世界上每天都有幾百萬人在用 E-mail ,因此其應用的可能性也遠遠超出了這個系列所介紹的處理方法。無論如何,我都希望這篇文章可以作為一個基礎為你服務,幫你開始想像各種可能性。
E-mail 如何工作
原則上來講,E-mail是簡單的。你可以用一個郵件用戶代理(mail user agent-MUA)創建帶有一個或幾個接收者地址的消息。有很多種形式的 MUAs 可供選擇,包括基于文本的、基于Web的、還有GUI應用程序。Microsoft Outlook 和 Netscape Messenger 屬于最后一種。每個e-mail 客戶端都被配置為向一個郵件傳輸代理(mail transfer agent --MTA)發送郵件和從一個MTA獲取發給某個用戶地址的e-mail消息。要想這樣做, 你需要在郵件服務器(技術上講,是MTA)上有一個e-mail 賬號 ,并且你能夠使用標準的Ineternet協議,無論是脫線處理 e-mail (用POP3)還是把 e-mail 留在服務器上(用IMAP)。在客戶端和MTA之間以及MTA和MTA之間發送郵件的協議都是簡單郵件傳輸協議(Simple Mail Transfer Protocol-SMTP)。

Building a James application
這個系列的第二部分在你了解James基礎設施的基礎上實現一個實際的應用程序.

在MTA之間究竟發生了什么事情僅僅稍微有趣一點。 E-mail服務器在很大程度上依賴于DNS 和被稱為郵件傳輸( mail transfer 或 MX)記錄的e-mail-specific 記錄。MX記錄與用來解析URL的DNS記錄稍有不同, 它還包含了一些額外的優先級信息來更高效的路由郵件。我不在這里深入研究這些細節 ,但明白DNS是成功有效的路由e-mail的關鍵很重要。 James 是一個 MTA, 同時JavaMail API 提供了一個 MUA的框架。在這篇文章里,我們將用JavaMail 來為我們的James 安裝做一次測試。在這個系列的第二篇文章里,我們將用James Mailet API來說明如何開發你自己的James應用程序。
James 的設計目標
James的設計要滿足特定的目標。例如,它完全用Java語言編碼以滿足最大化可移植能力的目標。它即提供了保護自身服務器環境的一些安全特性也提供了安全以實現安全的目標。 James 所具有的多線程應用程序的功能利用了很多Avalon框架提供的好處。 (Avalon 是一個Apache Jakarta 項目, 體現了Phoenix高性能服務器基礎設施的一些特性。了解 Avalon對于開發James應用程序是有益但不必要的。請看 資源 部分深入學習Avalon.)
James提供了一組全面的服務,包括一些僅僅在高端的或很好的郵件服務器中才能得到的。這些服務主要是用Matcher 和 Mailet APIs實現的,它們合作提供e-mail的檢測和處理能力。James支持標準的e-mail協議(SMTP, POP3, IMAP),和一些其他的協議。James采用松散耦合的嵌入式設計以保證消息框架與協議無關。這是一個很好的主意,將來可以讓James像大多數消息服務器一樣或者支持諸如即時消息那樣的消息協議。
設計組最后提出的也是最有趣的目標是mailets的概念,它為開發e-mail應用程序提供了一個基于組件生命周期和容器的解決方案。毋庸置疑,總是有可能會用到其他的MTA,比如 Sendmail。如果你想調用其他的MTA,那么你應該能夠調用任何程序,并且可以操作通過的數據。 但James提供了一個通用的、簡單的API實現這些目標,并且使任務更容易完成。感謝James提供的那些我們可以操作的對象,我們會在這篇文章中深入研究Matcher 和 Mailet APIs。
安裝并配置James
James可以從它在Apache基金會站點中的主頁(參見資源 提供的鏈接).上獲取,你應該下載最新發布的產品開始工作;在寫這篇文章的時候是版本2.1.2。你可以在James主頁左邊的導航欄里選擇 Downloads > Binaries 進入下載區。在下載區,找到Release Builds 部分并且選擇James 2.1鏈接,根據你個人的喜好選擇下載james-2.1.2.tar.gz 或者james-2.1.2.zip文件。
我們還要用JavaMail API測試我們的應用,所以你還需要下載它 (參見 資源)。現在能得到是1.3版本,文件名是 javamail-1_3.zip。當你到JavaMail的主頁上時,你會注意到有到JavaBeans Activation Framework (JAF)的鏈接,它是JavaMail API 需要的。 (參見 資源 直接鏈接到JAF.) JAF 現在的發布版本是 1.0.2 ,文件名是jaf-1_0_2.zip。一旦你得到了所有這些文件,你就能夠架起與James一起工作的系統了。
Well set up a directory structure with all the elements we need for development.我們會為開發用到的所有元素設立一個目錄結構。 在產品中,這種設立必須有所不同,文件的安排要綜合考慮安全性和功能性兩方面的問題。比如說,為了實現我們的目標,可以在本地主機上工作,但對于一個真正的e-mail服務器的部署工作來說,本地主機并不是一個可行的備選方案。如果你要為商業應用把James服務器部署為一個主MTA或與Sedmail一起工作,這里有大量的配置文檔和提供幫助的郵件列表。
當所有文件都解壓到James目錄下后, 我們的目錄層次結構將如列表1所示。我已經移走了 javadoc, src,和JavaMail webapp demo 目錄下的一些子目錄,以便我們的目錄更緊湊和易于想像。
列表1. James, JavaMail, 和 JAF 目錄
================================================================================
James
+—jaf-1.0.2
| +—demo
| \—docs
| \—javadocs
+—james-2.1.2
| +—apps
| +—bin
| | \—lib
| +—conf
| +—docs
| | +—images
| | \—stylesheets
| +—ext
| +—lib
| +—logs
\—javamail-1.3
+—demo
| +—client
| +—servlet
| \—webapp
+—docs
| \—javadocs
\—lib
===============================================================================
我假設你已經安裝了獨立于James文件的Java 平臺的1.4版本。James配置文件聲稱在使用Java 1.3.0時已經發現了一些問題,所以你應該使用1.3.1或更高的版本。原則上來說,James應該可以在與Java 1.4 VM兼容的任何平臺上很好的運轉。
我們的第一步是啟動James, 因為只有服務器被運行過一次以后配置文件才會被釋放出來。你會在 james-2.1.2/bin目錄下發現一個運行腳本 (根據你的操作系統使用run.bat 或 run.sh) 。當你運行這個腳本后,輸出應該和列表 2相似 (這是在Windows系統下的輸出樣本):
列表2. James運行時的控制臺輸出

================================================================================
Using PHOENIX_HOME: D:\James\james-2.1.2
Using PHOENIX_TMPDIR: D:\James\james-2.1.2\temp
Using JAVA_HOME: c:\programming\java14

Phoenix 4.0.1

James 2.1.2
Remote Manager Service started plain:4555
POP3 Service started plain:110
SMTP Service started plain:25
NNTP Service started plain:119
Fetch POP Disabled
================================================================================
你可以按 Ctrl+C 退出程序, Phoenix 容器會發出一個消息告訴你它正在退出。嚴格的講,正確的退出James的方法是使用遠程管理界面。我在我的開發環境里已經用過Ctrl+C,沒有發現負面的影響。但無論如何,在開發環境里總是應該使用shutdown命令。
在第一次關閉了James之后,你就會在james-2.1-2/apps/james/SAR-INF文件夾下面發現config.xml文件,你應該認真看一下這個文件。通常你應該做的第一件事是改變管理員賬號,默認設置為root,密碼是root。由于是進行開發,所以我們不管它,但很明顯在生產系統中保留這種配置是很不明智的。接下來要改變的通常是DNS服務器的地址,如果James是完全作為一個e-mail服務器運轉的話,這是非常必要的。既然我們所有的測試都是在本機上進行的,我們也不去管它。 但你應該意識到這是個很重要的設置。雖然理解配置文件很重要,但對于我們的開發目標來說,其余的默認設置都沒有問題。你可以在 james-2.1.2/docs目錄下得到更詳細的信息。
讓我們在開始工作之前先添加幾個用戶。首先用命令“telnet localhost 4555” telnet到本機的4555端口。可以用root這個用戶名和密碼登錄,登錄成功之后,我們就可以添加用戶了。“adduser” 命令需要用戶名和密碼兩個參數。在這個項目中我們會添加用戶名為red、 green和 blue的三個用戶,密碼都和用戶名相同。 (我相信你知道這在創建真實用戶的時候不是一個好主意,但這樣很容易配置我們的測試用例。) 添加用戶之后,你可以用”listusers“ 命令驗證輸入是否正確,然后鍵入”quit“命令退出遠程管理。整個會話如列表3所示,紅色的文本表示你自己鍵入的命令。(可惜看不到紅色了,:( )
列表3. 用遠程管理添加用戶
===============================================================================
JAMES Remote Administration Tool 2.1.2
Please enter your login and password
Login id:
root
Password:
root
Welcome root. HELP for a list of commands
adduser red red
User red added
adduser green green
User green added
adduser blue blue
User blue added
listusers
Existing accounts 3
user: blue
user: green
user: red
quit
Bye
================================================================================
現在我們和運行起來的James服務器一起大干一場了。如你所見,James的部署和用遠程管理進行配置是相當簡單的。很明顯,如果想讓郵件服務器安全的話你將需要改變幾個配置參數,但那并不是一個很復雜的過程。 使用郵件服務器真正關鍵的是在多用戶多服務環境中正確的配置DNS。這超出了本文的討論范圍,但它也不是很復雜的過程。
用JavaMail測試James
為了確保我們的安裝是成功的, 我們將很快的編寫能夠發送消息和顯示收件夾中的內容列表的兩個類,用來模擬典型的e-mail客戶端的基本功能。well write a quick pair of classes that will send messages and list inbox content, simulating the base functionality of a typical e-mail client. 我們用兩個類是因為 MailClient 類,如列表4所示,能夠重用以測試更復雜的行為,我們在開發自己的James應用程序時(本系列的第二篇文章)將會重用這個類。
列表4. MailClient: 模擬一個e-mail 客戶端的基本功能
===========================================

import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

public class MailClient
extends Authenticator
{
public static final int SHOW_MESSAGES = 1;
public static final int CLEAR_MESSAGES = 2;
public static final int SHOW_AND_CLEAR =
SHOW_MESSAGES + CLEAR_MESSAGES;

protected String from;
protected Session session;
protected PasswordAuthentication authentication;

public MailClient(String user, String host)
{
this(user, host, false);
}

public MailClient(String user, String host, boolean debug)
{
from = user + @ + host;
authentication = new PasswordAuthentication(user, user);
Properties props = new Properties();
props.put(“mail.user”, user);
props.put(“mail.host”, host);
props.put(“mail.debug”, debug ? “true” : “false”);
props.put(“mail.store.protocol”, “pop3”);
props.put(“mail.transport.protocol”, “smtp”);
session = Session.getInstance(props, this);
}

public PasswordAuthentication getPasswordAuthentication()
{
return authentication;
}

public void sendMessage(
String to, String subject, String content)
throws MessagingException
{
System.out.println(“SENDING message from ” + from + ” to ” + to);
System.out.println();
MimeMessage msg = new MimeMessage(session);
msg.addRecipients(Message.RecipientType.TO, to);
msg.setSubject(subject);
msg.setText(content);
Transport.send(msg);
}

public void checkInbox(int mode)
throws MessagingException, IOException
{
if (mode == 0) return;
boolean show = (mode %26amp; SHOW_MESSAGES) > 0;
boolean clear = (mode %26amp; CLEAR_MESSAGES) > 0;
String action =
(show ? “Show” : “”) +
(show %26amp;%26amp; clear ? ” and ” : “”) +
(clear ? “Clear” : “”);
System.out.println(action + ” INBOX for ” + from);
Store store = session.getStore();
store.connect();
Folder root = store.getDefaultFolder();
Folder inbox = root.getFolder(“inbox”);
inbox.open(Folder.READ_WRITE);
Message[] msgs = inbox.getMessages();
if (msgs.length == 0 %26amp;%26amp; show)
{
System.out.println(“No messages in inbox”);
}
for (int i = 0; i < msgs.length; i++)
{
MimeMessage msg = (MimeMessage)msgs[i];
if (show)
{
System.out.println(” From: ” + msg.getFrom()[0]);
System.out.println(” Subject: ” + msg.getSubject());
System.out.println(” Content: ” + msg.getContent());
}
if (clear)
{
msg.setFlag(Flags.Flag.DELETED, true);
}
}
inbox.close(true);
store.close();
System.out.println();
}
}
===========================================
設計MailClient的主要目的是讓我們發送消息,顯示或者刪除給定用戶在服務器上的消息列表。我已經聲明了一些有用的常量,讓我們 顯示消息SHOW_MESSAGES,清除消息 CLEAR_MESSAGES, 或者執行這兩種操作。 MailClient類還實現了 Authenticator接口,以便在檢索郵件時的在線處理更容易管理。
我創建了兩個構造函數,其中一個顯式的設置JavaMail的調試標志。在調試狀態下,程序會把客戶端/服務器的交互協議輸出到控制臺,這樣就能看到發生了什么。 短的構造方法不打開調試標志,另外兩個參數是用戶名和主機,e-mail地址可以由用戶名和主機得到。我們創建了一個在Authenticator接口中定義的 PasswordAuthentication 對象,這個對象可以由getPasswordAuthentication()方法獲得。
構造函數的其余代碼創建了JavaMail properties來保存所說明的用戶名和主機,并且顯式的說明了我們要用到的協議。一旦我們將這些值存入Properties對象,我們就能調用靜態的Session 方法 getInstance() 來得到一個有效的Session 引用, 然后將它保存在局部變量中 。一旦構造函數被用于指定的用戶,我們就準備好在指定的e-mail主機上發送或檢索那個用戶的e-mail。
sendMessage() 方法同樣很簡單。它用指定的接收者、主題和文本內容創建了一個 MimeMessage 對象,然后使用 JavaMail中Transport 類的靜態方法 send() 發送這個消息。為了看清楚發生了什么,我們把這個過程也輸出到控制臺。
checkInbox() 方法做的工作比較多,因為它要列出消息列表,并可以根據選擇刪除它們。method does more work because it needs to list messages and, optionally, erase them. 也可以不查看直接刪除消息,這取決于你在mode參數中使用的標志。Its also possible to just erase messages without looking at them, depending on the flags you use for the mode argument. 為了實際得到消息,我們需要通過session獲得一個Store的引用。連接到服務器,然后打開收件箱文件夾。我們得到一個文件夾的引用之后,就可以循環顯示或刪除消息。
現在我們有了可重用的 MailClient 代碼,我們可以為本機上的James服務器編寫一個快速的測試代碼了。列表5中的 JamesConfigTest 類創建了3個MailClient類的實例,分別代表我們創建的用戶 (red、 green和 blue). 在你執行這段代碼之前,確保那些用戶在e-mail服務器上是有效的。
列表5. JamesConfigTest: James 服務器的一個快速測試
===========================================

public class JamesConfigTest
{
public static void main(String[] args)
throws Exception
{
// CREATE CLIENT INSTANCES
MailClient redClient = new MailClient(“red”, “localhost”);
MailClient greenClient = new MailClient(“green”, “localhost”);
MailClient blueClient = new MailClient(“blue”, “localhost”);

// CLEAR EVERYBODYS INBOX
redClient.checkInbox(MailClient.CLEAR_MESSAGES);
greenClient.checkInbox(MailClient.CLEAR_MESSAGES);
blueClient.checkInbox(MailClient.CLEAR_MESSAGES);
Thread.sleep(500); // Let the server catch up

// SEND A COUPLE OF MESSAGES TO BLUE (FROM RED AND GREEN)
redClient.sendMessage(
“blue@localhost”,
“Testing blue from red”,
“This is a test message”);
greenClient.sendMessage(
“blue@localhost”,
“Testing blue from green”,
“This is a test message”);
Thread.sleep(500); // Let the server catch up

// LIST MESSAGES FOR BLUE (EXPECT MESSAGES FROM RED AND GREEN)
blueClient.checkInbox(MailClient.SHOW_AND_CLEAR);
}
}
===========================================
創建了3個MailClient 實例之后, JamesConfigTest 先簡單的用 checkInbox()方法以CLEAR_MESSAGES 模式清除每個郵箱,并且等待半秒以確保服務器處理完刪除操作。接著分別從red和green發送一個消息到blue 。然后檢查blue賬號里的消息。當你運行JamesConfigTest的時候,你應該看到如列表6的輸出:
列表6. JamesConfigTest運行時的輸出
===========================================

Clear INBOX for red@localhost

Clear INBOX for green@localhost

Clear INBOX for blue@localhost

SENDING message from red@localhost to blue@localhost

SENDING message from green@localhost to blue@localhost

Show and Clear INBOX for blue@localhost
From: green@localhost
Subject: Testing blue from green
Content: This is a test message

From: red@localhost
Subject: Testing blue from red
Content: This is a test message
===========================================
這表明我們的James安裝是成功的;在進行開發之前你需要按這種方式設置你的系統。然而,我們在這個系列的第二部分之前不會談論到開發的問題。在這篇文章的剩余部分,我們將研究一下Matcher和Mailet API,以及隨James發布版本一起提供的現成的匹配器和mailets。我們還將快速瀏覽一下James支持的其它特性。
匹配器
James自帶了一些標準的匹配器(matchers)。它們全都實現了Matcher API,如列表7所示,并且提供了現有的MTA一般都有的功能,還提供了一些實用的擴展功能。這個接口非常簡單;它包含了一對生命周期方法,init() 和 destroy() ,還有一對記錄方法getMatcherInfo() 和 getMatcherConfig(),以及一個主方法,match() ,對Mail對象進行操作。Mail引用提供了容器狀態的訪問、郵件消息和要進行操作的元數據。
列表7. The Matcher 接口
===========================================

public interface Matcher
{
void init(MatcherConfig config);
void destroy();
String getMatcherInfo();
MatcherConfig getMatcherConfig();
Collection match(Mail mail);
}
===========================================
匹配器的任務是識別一組接收者,并返回一個代表要被mailet處理的接收者的字符串對象集合。通過結合匹配器的識別能力和mailet的處理能力,可以開發出復雜的e-mail消息處理應用程序。
隨James一起發布的匹配器使你無需開發自己的匹配器就能做一些事情。在決定開始開發自己的匹配器之前最好先了解一下這些已有的匹配器。通常的情況下,你想做的工作可能已經幫你做好了。你可以在表格1中看到這些已有的匹配器:
表格 1. James自帶的匹配器(matchers)
Matcher Description
All 匹配所有的e-mail并返回所有的接收者
HasHeader 匹配含有指定的頭信息的消息
HasAttachment 匹配帶有附件的消息
SubjectStartsWith 匹配標題以指定的文本開頭的消息
SubjectIs 匹配含有指定的標題消息
HostIs 匹配來自指定的主機的消息
HostIsLocal 匹配本機產生的消息
UserIs 匹配指定的用戶的消息
SenderIs 匹配指定的發送者的消息
SenderInFakeDomain 匹配發送者的主機地址不能解析的消息
SizeGreaterThan 匹配比指定的限制大的消息
Recipients 匹配接收者在指定的列表中的消息
RecipientsLocal 匹配接收者在本地的消息
IsSingleRecipient 匹配僅有一個接收者的消息
RemoteAddrInNetwork 匹配來自指定的IP地址、域等列表的消息
RemoteAddrNotInNetwork 匹配不是來自指定的IP地址、域等列表的消息
RelayLimit 匹配轉發次數大于指定的服務器數的消息。
InSpammerBlackList 與mail-abuse.org提供的列表中的地址匹配
NESSpamCheck 采用得自Netscape Mail Server的方法匹配垃圾郵件
HasHabeasWarrantMark 采用Habeas Warrant匹配郵件
FetchedFrom 與FetchPOPMatches所用的 X-fetched-from 頭信息匹配
CommandForListserv 匹配目錄服務器的命令

正如你在表中所看到的,你不用編寫任何新的代碼就可以完成很多任務了,包括諸如匹配頭、主題、接收者這樣的原子級任務,以及像檢測垃圾郵件和處理目錄服務器命令這樣的高層任務。
Mailets
James 的很多特性是通過列表8中Mailet API 實現的,熟悉Servlet API的開發者可能會覺得奇怪,它看起來很眼熟。與Matcher API一樣,Mailet接口支持兩個生命周期方法,一個提供初始化(init() 方法),一個停止服務(destroy() 方法)。還有兩個返回信息的方法,getMailetInfo(), 返回一個包含作者、版本、該mailet的版權等信息的字符串對象,getMailetConfig()很實用,它返回mailet的配置信息。init()方法有一個MailetConfig對象作為參數,雖然這個對象可能被修改,但它通常是由getMailetConfig()提供的。
列表 8. The Mailet 接口

===========================================
public interface Mailet
{
void init(MailetConfig config);
void destroy();
String getMailetInfo();
MailetConfig getMailetConfig();
void service(Mail mail);
}
===========================================
services() 方法以一個Mail 對象為參數,完成主要的處理工作。Maile對象提供了對容器狀態、郵件消息和要進行處理的元數據的訪問。
表格2是James已有的mailet實現的列表,它可以給你一個James支持的特性和已有的mailet應用程序的類型的概念。
表格2. James自帶的 mailets
Mailet Description
Null 結束e-mail消息的處理
AddHeader 給消息內容加一個文本的頭信息
AddFooter 給消息內容加一個文本的腳信息
Forward 將消息轉發給列表中的接收者
Redirect 提供可配置的轉發服務
ToProcessor 將e-mail處理轉發給一個指定的處理器
ToRepository 將消息復制到指定的目錄下
NotifySender 將消息作為附件轉發給原始的發送者
NotifyPostmaster 將消息作為附件轉發給postmaster
RemoteDelivery 管理SMTP主機的發送
LocalDelivery 將消息發送到本地郵箱
JDBCAlias 使用JDBC數據源進行別名翻譯
JDBCVirtualUserTable 使用JDBC數據源進行更復雜的別名翻譯
UseHeaderRecipient 從消息的頭信息中重建郵件的接收者
ServerTime 發送一個帶有服務器時間戳的消息
PostmasterAlias 將 postmaster@ 的消息轉發到一個個人的地址中
AddHabeasWarrantMark 給消息添加一個Habeas Warrant標記
AvalonListserv 提供一個基本的目錄服務器功能
AvalonListservManager 處理目錄服務器的管理命令

從這個列表可以看出,有幾個James所支持的特性要歸功于Mailet API,包括復雜的目錄服務器支持、別名、存儲和路由能力。
其它特性
除了這個系列所論述的,James還有很多其它的功能。我們會在這里簡單的介紹 以使你更好的了解James的實際能力。首先是對NNTP的支持,讓James可以作為一個Usenet服務器。James還實現了FetchPOP協議,能夠支持基于郵件的遠程管理。RemoteManager 和SpoolManager 提供了多類型存儲和管理的抽象,能夠支持多種類型的存儲和管理。雖然James支持部分或全部的以數據庫為中心的解決方案,但對于開發而言,使用基于SpoolManager的文件系統就足夠了。
James提供了高效的用戶管理接口和服務,并且支持郵件列表。 實際上,郵件列表功能是James提供的服務中最常用的,通常也是管理員選擇James作為e-mail解決方案的原因。
下篇內容簡介
James基礎設施的設計目標是靈活性和易于進行應用開發。E-mail 應用的可能性是無限的。在這個系列的 follow-up installment 中,我們將開發一個簡單的應用程序提供假期消息功能,允許用戶向一個特定的James地址發送e-mail打開假期消息功能。用戶可以起草一封e-mail作為自動答復消息,在用戶向另一個特定的James地址發送取消消息關閉假期消息功能之前,James會用答復消息自動答復該用戶收到的消息。e-mail客戶端軟件通常會提供這種機制,但客戶端軟件通常會受到地理位置的限制,而且如果客戶端關了的話,這個功能就不起作用了。通過在e-mail服務器上實現這個功能,我們可以不受限制的在任何地方檢查我們的郵件,而且我們也能夠很容易根據計劃的變化情況修改回復消息,以使答復更確切。
資源
下載這篇文章里用到的源代碼
ftp://www6.software.ibm.com/software/developer/library/j-james1.zip

從 Apache James主頁下載James包
http://james.apache.org/

從Avalon 項目主頁深入學習Avalon
http://avalon.apache.org/

要執行這篇文章中的示例代碼,你需要下載JavaMail API 和 JavaBeans Activation Framework.
http://java.sun.com/products/javamail
http://java.sun.com/beans/glasgow/jaf.html

在教程 “Fundamentals of JavaMail API” (developerWorks, August 2001)深入學習 JavaMail .
http://www-106.ibm.com/developerworks/edu/j-dw-javamail-i.html


About the author
Claude Duguay has developed software for more than 20 years. He is passionate about the Java platform, reads about it incessantly, and writes about it as often as possible. You can reach him at claude.duguay@verizon.net.,

贊(0)
版權申明:本站文章部分自網絡,如有侵權,請聯系:west999com@outlook.com 特別注意:本站所有轉載文章言論不代表本站觀點! 本站所提供的圖片等素材,版權歸原作者所有,如需使用,請與原作者聯系。未經允許不得轉載:IDC資訊中心 » 企業級郵件服務器apache james介紹(1)_郵件服務器
分享到: 更多 (0)
宅男午夜福利美女来袭|欧美三级电影|影音先锋成人av共享|亚洲快播日韩AV手机在线观看