并不是在研究邮件服务器实现,这两天学习用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研究透了。之后我可能会写一篇相关的文章,在这就很少说了。但愿这篇文章可以对你们有所启发!有所帮助!祝你们工做顺利!