James 是一个企业级的邮件服务器,它完全实现了smtp 和 pops 以及nntp 协议。同时,james服务器又是一个邮件应用程序平台。James的核心是Mailet API,而james 服务齐是一个mailet的容器。它可以让你非常容易的实现出很强大的邮件应用程序。James开源项目被广泛的应用于与邮件有关的项目中。你可以通过它来搭建自己的邮件服务器。我们可以利用Mailet API,编程接口来实现自己所需的业务。James集成了Avalon 应用程序框架以及
Phoenix Avalon
框架容器。
Phoenix
为
james
服务器提供了强大的支持。需要说明的是
Avalon
开源项目目前已经关闭。
现在让我们开始我们激动人心的
james
之旅。首先我们将
james-binary-2.3.1.zip
解压缩下载到你的安装目录。我们可以把这个过程理解为安装的过程。我在这里将它解压到
c:\.
并且把它改名为
james.
这样我们的
james
就安装好了。目录为
C:\james
。很简单吧!
准备知识 - 学习一些必要的知识
在我使用
james
的时候让我感觉首先理解
james
的应用程序结构是很重要的。否则你会在使用中感到很困惑。
它的应用程序结构是这样的:
James
|_ _apps
|_ _bin
|_ _conf
|_ _ext
|_ _lib
|_ _logs
|_ _tools
我们重点介绍一下两个文件夹
bin
和
apps.
bin
目录中的
run.bat
和
run.sh
是
James
的启动程序。只要记住这个重要文件就可以。
启动之后控制台显示如下:
Using PHOENIX_HOME: C:\james
Using PHOENIX_TMPDIR: C:\james\temp
Using JAVA_HOME: C:\j2sdk1.4.2_02
Using PHOENIX_TMPDIR: C:\james\temp
Using JAVA_HOME: C:\j2sdk1.4.2_02
Phoenix 4.2
James Mail Server 2.3.1
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.1
Please enter your login and password
Login id:
root
Password:
root
Welcome root. HELP for a list of commands
3.
添加用户
adduser kakaxi kakaxi
User kakaxi added
Adduser mingren mingren
User mingren added
4.
查看添加情况
listusers
Existing accounts 2
user: mingren
user: kakaxi
得到上面的信息说明我们已经添加成功。
发送器
这个类主要用来测试我们的邮件服务器,可以不用将其打入包中。
java 代码
- package com.yy.jamesstudy;
- 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 = "kakaxi";
- password = "kakaxi";
- mailServer = "localhost";
- From = "kakaxi@localhost";
- To = "mingren@localhost";
- mailSubject = "Hello Scientist";
- MailContent = "How are you today!";
- }
- public void send(){
- EmailAuthenticator mailauth =
- new EmailAuthenticator(username, password);
- // 设置邮件服务器
- prop = System.getProperties();
- 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);
- }
- }
<v:shapetype id="_x0000_t75" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" filled="f" stroked="f" coordsize="21600,21600" o:spt="75"> </v:shapetype>
实现-Matcher 和 Mailet编写
我先解释一下大概的流程:当
james
接收到一个
smtp
请求时首先会交给
matcher
来进行一系列过滤动作。然后由
matcher
交给相应的
mailet
来进行处理。
James
就相当于一个
matcher
和
mailet
的容器。就像
tomcat
之于
servlet
。而
mailet
和
servlet
很是相似。
我们这里要完成的功能很简单,就是当
james
邮件服务器接收到鸣人(人名)后把发送者和邮件正文打印到控制台。我们分析这个需求发现我们需要写一个
matcher
以及一个
mailet.matcher
用来过滤而
mailet
用来将邮件内容打印到控制台。为了简单起见,我这次只是继承了
GenericMailet
和
GenericRecipientMatcher
两个已经实现的
mailet
和
matcher.
具体的
Matcher
和
Mailet
的使用我以后会整理成另外一篇文章。
Matcher
的实现
- package com.yy.jamesstudy;
- import javax.mail.MessagingException;
- import org.apache.mailet.GenericRecipientMatcher;
- import org.apache.mailet.MailAddress;
- /**
- * 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("mingren")!=-1) {
- return true;
- }
- return false;
- }
- }
GenericRecipientMatcher
是一个针对收件人进行过滤的
matcher
.
Mailet
的实现
- package com.yy.jamesstudy;
- import java.io.IOException;
- import javax.mail.MessagingException;
- import javax.mail.internet.MimeMessage;
- import org.apache.mailet.GenericMailet;
- import org.apache.mailet.Mail;
- import org.apache.mailet.MailAddress;
- /**
- * 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
文件发布到
C:\james\apps\james\SAR-INF\lib。
注意:如果没有找到相关目录,则需要先启动一遍james,相关的文件夹才会被创建。还有一点需要特别说明:lib目录是通过我们手动创建的。
2.
将
Matcher
和
Mailet
发布到
config.xml
中,
config.xml
在
james\apps\james\SAR-INF\
下
1
)我们首先找到如下内容
- <mailetpackages>
- <mailetpackage>org.apache.james.transport.mailetsmailetpackage>
- <mailetpackage>org.apache.james.transport.mailets.smimemailetpackage>
- mailetpackages>
- <matcherpackages>
- <matcherpackage>org.apache.james.transport.matchersmatcherpackage>
- <matcherpackage>org.apache.james.transport.matchers.smimematcherpackage>
- matcherpackages>
2
)加入包声明
- <mailetpackages>
- <mailetpackage>com.yy.jamesstudymailetpackage>
- <mailetpackage>org.apache.james.transport.mailetsmailetpackage>
- <mailetpackage>org.apache.james.transport.mailets.smimemailetpackage>
- mailetpackages>
- <matcherpackages>
- <matcherpackage>com.yy.jamesstudy matcherpackage>
- <matcherpackage>org.apache.james.transport.matchersmatcherpackage>
- <matcherpackage>org.apache.james.transport.matchers.smimematcherpackage>
- matcherpackages>
3
)加入
Matcher
和
Mailet
的关联关系
找到
<processor name="root"></processor>
元素在它的下面加入
xml 代码
- <mailet match="BizMatcher" class="BizMaillet"/>
Mailet
元素代表了一个
matcher
和一个
mailet
的组合。
Match
属性:是指
matcher
的类名。而
class
属性:是指
mailet
的类名。
最后别忘了,保存退出。并且重新启动james服务器。
测试- 验证我们的mail应用程序
我们主要通过
mail
类来测试我们的应用。还记得我们刚才写的那个
mail
类吗?!在那个类中我们初始化了相关的信息
.
username = "kakaxi";
password = "kakaxi";
mailServer = "localhost";
From = "kakaxi@localhost";
To = "mingren@localhost";
mailSubject = "Hello Scientist";
MailContent = "How are you today!";
发件人是卡卡西,收件人是
mingren.
这两个用户我们在前面都已经创建完毕。我们用他们来测试
james
的邮件收发以及
mailet api
的应用。
根据需求假设我们发给
james
服务器(这里是
james
的默认配置:
localhost
)
的邮件的收件人是鸣人。那么我们就能通过
matcher
监测到这封邮件,并且调用相应的
maile
t
来进行处理。由
mailet
打印出相应的邮件发送者和正文。
运行
Mail
类后得到
Using PHOENIX_HOME: C:\james
Using PHOENIX_TMPDIR: C:\james\temp
Using JAVA_HOME: C:\j2sdk1.4.2_02
Using PHOENIX_TMPDIR: C:\james\temp
Using JAVA_HOME: C:\j2sdk1.4.2_02
Phoenix 4.2
James Mail Server 2.3.1
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
研究透了。以后我可能会写一篇相关的文章,在这就不多说了。希望这篇文章能够对大家有所启发!有所帮助!祝大家工作顺利!