`

用 Apache James 搭建邮件服务器来收发邮件实践

 
阅读更多

文章转载http://www.cnblogs.com/liyazhou

 

 

Apache James 简称 James, 是 Java Apache Mail Enterprise Server的缩写。James 是100%基于Java的电子邮件服务器。它是一种独立的邮件服务器,并提供了一个完整的电子邮件解决方案,用来收、发电子邮件。

 

本文不赘述James服务器的参数细节,这个以后有机会再详细讨论,这里先从服务器搭建开始,用搭建的服务器收、发电子邮件来熟悉一下Apache James。本人也是新手,希望能得到各位高手的指点,使大家能悟到进阶的方向。

 

开始之前,先声明一下本文操作的系统环境:

1. JDK 6u10b

2. JMail API v1.4.2

3. JAF API v1.1(JavaBean Activation Framework)

4. Apache James 2.3.1

5. Eclipse 3.4 for J2EE Developers

6. Windows 2000 Server sp4

 

 

 

1。请下载安装JDK,并设置好其环境变量:JAVA_HOME=…… 、PATH=…… 、CLASSPATH=…… Eclipse 3.4 是目前的最新版本,可以从http://www.eclipse.org/下载。

 

2。请下载JMail API、JAF API,可以在www.java.sun.com找到他们,找不到也不要紧,本文附件示例代码免费提供一份(^_^)。

 

3。Apache James 的官方网站为:http://james.apache.org/,当前 Server的最新版为 2.3.1版. 安装非常简单,下载后得到james-binary-2.3.1.zip 文件,解压后即可。这里假设解压到D盘(D:\james-2.3.1),目录结构如下:

 

D:\james-2.3.1

|--- apps

|--- bin

|

…………

 

4。启动 James 服务器

双击或在命令行下执行D:\james-2.3.1\bin 目录下的 run.bat文件,即可启动 James 服务器。

 

启动后能在控制台看到如下信息,说明启动成功:

 

Java代码
  1. UsingPHOENIX_HOME:D:\james-2.3.1
  2. UsingPHOENIX_TMPDIR:D:\james-2.3.1\temp
  3. UsingJAVA_HOME:D:\Java\jdk1.6.0_10
  4. Phoenix4.2
  5. JamesMailServer2.3.1
  6. RemoteManagerServicestartedplain:4555
  7. POP3Servicestartedplain:110
  8. SMTPServicestartedplain:25
  9. NNTPServicestartedplain:119
  10. FetchMailDisabled

 

 

 

要关闭 James 服务,请使用 Ctrl + C

 

说明:启动前请确保您的JDK环境变量如JAVA_HOME等已经设置好;James 启动时,其SMTP 服务默认在 25 端口启动,POP3 服务默认在 110 端口启动, NNTP 服务默认在 119 端口启动, 请确保这些端口未被占用。比如本系统下就已经安装了Microsoft的 SMTP 服务,造成 James无法启动,解决方法为:开始--->设置--->控制面板--->管理工具--->服务,打开后找到“Simple Mail Transport Protocol(SMTP)”服务项,关闭即可。

 

 

5。配置服务

服务器启动后会在本机配置一个默认的服务,这可以用来在本机上本服务器范围内收发邮件,但是邮件发不到163等外网邮箱。我们这里关注的重点就是配置一个能发到外网如163这样的邮箱的邮件,这样才有价值。不过由于本人是在本机上测试,一时不能获取公司的域名参数,无法测试接收外网邮箱(如163)的邮件,见晾,不过做法都是一样的,至少我们可以向外网邮箱发送邮件,局域网内可以收、发邮件。

 

打开D:\james-2.3.1\apps\james\SAR-INF 下的 config.xml 文件,初次启动James之前,不会有这个文件,只有当James服务启动一次之后才自动构件该文件。

 

找到

 

Java代码
  1. ……
  2. <postmaster>Postmaster@localhost</postmaster>
  3. ……
  4. <servernamesautodetect="true"autodetectIP="true">
  5. <servername>localhost</servername>
  6. </servernames>
  7. ……

 

 

 

把localhost该成你自己想要的邮箱域名,把自动探测IP属性设置为“false”这里假设改成 zhaipuhong.com如果开了一个帐号 zph ,那么他的邮件地址就是zph@zhaipuhong.com(^_^)修改结果如下:

 

 

Xml代码
  1. ……
  2. <postmaster>Postmaster@zhaipuhong.com</postmaster>
  3. ……
  4. <servernamesautodetect="false"autodetectIP="false">
  5. <servername>zhaipuhong.com</servername>
  6. </servernames>
  7. ……

 

 

找到

 

Xml代码
  1. <mailetmatch="RemoteAddrNotInNetwork=127.0.0.1"class="ToProcessor">
  2. <processor>relay-denied</processor>
  3. <notice>550-Requestedactionnottaken:relayingdenied</notice>
  4. </mailet>

 

 

将其注释,结果如下:

 

Xml代码
  1. <!--mailetmatch="RemoteAddrNotInNetwork=127.0.0.1"class="ToProcessor">
  2. <processor>relay-denied</processor>
  3. <notice>550-Requestedactionnottaken:relayingdenied</notice>
  4. </mailet-->

 

 

找到下面元素,去掉其注释

 

Xml代码
  1. <authRequired>true</authRequired>

 

 

 

这样邮箱访问需要帐号验证,你不希望别人用你的帐号收发消息吧……^_^

 

如此,James服务配置已经完成。

 

 

6。创建邮件帐号

创建邮件帐号后,就可以用来收发邮件了。James的账号管理是通过基于Telnet客户机的远程管理器,这点颇为不爽,尤其是我的操作系统下的命令行控制台是不显示telnet命令输入字符的,经常出错。

 

现在进入命令行控制台,在telnet localhsot 4555 进入James管理器,操作如下:

 

C代码
  1. C:\DocumentsandSettings\db2admin>telnetlocalhost4555

 

 

 

将进入

 

C代码
  1. JAMESRemoteAdministrationTool2.3.1PleaseenteryourloginandpasswordLoginid:

 

 

 

默认的登陆id 为root 密码也为 root ,登陆成功后结果如下:

 

C代码
  1. JAMESRemoteAdministrationTool2.3.1
  2. Pleaseenteryourloginandpassword
  3. Loginid:
  4. Password:
  5. Welcomeroot.HELPforalistofcommands

 

 

创建新用户的命令是:adduser username password

这里创建了两个账户来作为演示使用: zhaipuhong/zhangpuhong; zph/zph

 

说明:你可以输入help来获取命令帮助

 

 

C代码
  1. helpdisplaythishelp显示帮助信息
  2. listusersdisplayexistingaccounts显示现有账户
  3. countusersdisplaythenumberofexistingaccounts显示现有账户数量
  4. adduser[username][password]addanewuser添加一个新用户
  5. verify[username]verifyifspecifieduserexist核实指定用户是否存在
  6. deluser[username]deleteexistinguser删除存在的用户
  7. setpassword[username][password]setsauser'spassword设置用户密码
  8. setalias[user][alias]locallyforwardsallemailfor'user'to'alias'设置邮箱别名
  9. showalias[username]showsauser'scurrentemailalias显示别名
  10. unsetalias[user]unsetsanaliasfor'user'删除用户别名
  11. setforwarding[username][emailaddress]forwardsauser'semailtoanotheremailaddress转发用户的电子邮件地址到另一个电子邮件地址
  12. showforwarding[username]showsauser'scurrentemailforwarding显示用户的当前邮件转发
  13. unsetforwarding[username]emovesaforward删除转发
  14. user[repositoryname]changetoanotheruserrepository改变另一个用户库
  15. shutdownkillsthecurrentJVM(convenientwhenJamesisrunasadaemon)关闭当前的服务
  16. quitcloseconnection关闭连接

 

 

 

 

 

 

 

 

账号创建成功后,使用quit退出管理器。现在我们可以开始部署我们的JMail应用了。

 

 

7。用James收发邮件

现在我们来写两个简单的程序来体验一下如何使用James收发邮件。请注意,示例程序是通用的。关于如何用JMail API收发邮件,这里不详细介绍,如果还没有接触过请参考一下我之前的文章:

http://zhaipuhong.javaeye.com/admin/blogs/213005

 

关于接受邮件部分,我们在代码中通过注释来描述。另外我们来回忆一下上述步骤配置James服务器的参数:

1。smtp 服务器:192.168.1.98或者localhost 192.168.1.98是我的局域网IP,由于我James服务就装在我的机器上,所以我可以用localhost

2。两个邮件帐号:zhaipuhong/zhaipuhong 对应邮箱地址: zhaipuhong@zhaipuhong.com

zph/zph 对应邮箱地址: zph@zhaipuhong.com

注意:邮箱域名我们配置的是zhaipuhong.com

 

示例程序:

 

 

Java代码
  1. packagecom.zhaipuhong.j2ee.jmail;
  2. importjava.io.IOException;
  3. importjava.util.Properties;
  4. importjavax.mail.Authenticator;
  5. importjavax.mail.Folder;
  6. importjavax.mail.Message;
  7. importjavax.mail.MessagingException;
  8. importjavax.mail.PasswordAuthentication;
  9. importjavax.mail.Session;
  10. importjavax.mail.Store;
  11. importjavax.mail.Transport;
  12. importjavax.mail.internet.InternetAddress;
  13. importjavax.mail.internet.MimeMessage;
  14. importjavax.mail.internet.MimeUtility;
  15. publicclassHelloJMail{
  16. //发送邮件
  17. publicstaticvoidsendMail(){
  18. //Stringhost="192.168.1.98";//指定的smtp服务器,本机的局域网IP
  19. Stringhost="localhost";//本机smtp服务器
  20. //Stringhost="smtp.163.com";//163的smtp服务器
  21. Stringfrom="zhaipuhong@zhaipuhong.com";//邮件发送人的邮件地址
  22. Stringto="zph@zhaipuhong.com";//邮件接收人的邮件地址
  23. finalStringusername="zhaipuhong";//发件人的邮件帐户
  24. finalStringpassword="zhaipuhong";//发件人的邮件密码
  25. //创建Properties对象
  26. Propertiesprops=System.getProperties();
  27. //添加smtp服务器属性
  28. props.put("mail.smtp.host",host);
  29. props.put("mail.smtp.auth","true");
  30. //创建邮件会话
  31. Sessionsession=Session.getDefaultInstance(props,newAuthenticator(){
  32. @Override
  33. publicPasswordAuthenticationgetPasswordAuthentication(){
  34. returnnewPasswordAuthentication(username,password);
  35. }
  36. });
  37. try{
  38. //定义邮件信息
  39. MimeMessagemessage=newMimeMessage(session);
  40. message.setFrom(newInternetAddress(from));
  41. message.addRecipient(Message.RecipientType.TO,newInternetAddress(
  42. to));
  43. //message.setSubject(transferChinese("我有自己的邮件服务器了"));
  44. message.setSubject("Ihavamyownmailserver");
  45. message.setText("Fromnow,youhaveyourownmailserver,congratulation!");
  46. //发送消息
  47. session.getTransport("smtp").send(message);
  48. //Transport.send(message);//也可以这样创建Transport对象发送
  49. System.out.println("SendMailProcessOver!");
  50. }catch(MessagingExceptione){
  51. e.printStackTrace();
  52. }
  53. }
  54. //接受邮件
  55. publicstaticvoidgetMail(){
  56. Stringhost="localhost";
  57. finalStringusername="zph";
  58. finalStringpassword="zph";
  59. //创建Properties对象
  60. Propertiesprops=newProperties();
  61. //创建邮件会话
  62. Sessionsession=Session.getDefaultInstance(props,newAuthenticator(){
  63. @Override
  64. publicPasswordAuthenticationgetPasswordAuthentication(){
  65. returnnewPasswordAuthentication(username,password);
  66. }
  67. });
  68. try{
  69. //获取邮箱的pop3存储
  70. Storestore=session.getStore("pop3");
  71. store.connect(host,username,password);
  72. //获取inbox文件
  73. Folderfolder=store.getFolder("INBOX");
  74. folder.open(Folder.READ_ONLY);//打开,打开后才能读取邮件信息
  75. //获取邮件消息
  76. Messagemessage[]=folder.getMessages();
  77. for(inti=0,n=message.length;i<n;i++){
  78. System.out.println(i+":"+message[i].getFrom()[0]
  79. +"\t"+message[i].getSubject());
  80. try{
  81. message[i].writeTo(System.out);
  82. }catch(IOExceptione){
  83. e.printStackTrace();
  84. }
  85. }
  86. //关闭资源
  87. folder.close(false);
  88. store.close();
  89. }catch(MessagingExceptione){
  90. e.printStackTrace();
  91. }
  92. System.out.println("GetMailProcessOver!");
  93. }
  94. //邮件主题中文字符转换
  95. publicstaticStringtransferChinese(StringstrText){
  96. try{
  97. strText=MimeUtility.encodeText(newString(strText.getBytes(),"GB2312"),"GB2312","B");
  98. }catch(Exceptionex){
  99. ex.printStackTrace();
  100. }
  101. returnstrText;
  102. }
  103. publicstaticvoidmain(String[]args){
  104. HelloJMail.sendMail();
  105. //HelloJMail.getMail();
  106. }
  107. }

 

 

 

 

 

说明: 执行测试时,先执行发送,在main方法中注释掉邮件接受方法调用,等待片刻,再注释掉邮件发送方法调用,执行邮件接受方法调用。因为就算163这样优秀的企业级邮箱也不可能瞬间就能收到发送的邮件。

在邮件发送方法中:sendMail(), 可以尝试一下又本邮件服务器向163邮箱发送邮件,如果想通过163邮件服务器想本地发送邮件,你需要配置DSN。

 

以下为本机接收James邮件服务器提供服务的邮件结果:

 

 

C代码
  1. 0:zhaipuhong@zhaipuhong.comIhavamyownmailserver
  2. Return-Path:<zhaipuhong@zhaipuhong.com>
  3. Delivered-To:zph@zhaipuhong.com
  4. Received:from127.0.0.1([127.0.0.1])
  5. byZPH(JAMESSMTPServer2.3.1)withSMTPID693
  6. for<zph@zhaipuhong.com>;
  7. Wed,9Jul200819:58:38+0800(CST)
  8. Date:Wed,9Jul200819:58:38+0800(CST)
  9. From:zhaipuhong@zhaipuhong.com
  10. To:zph@zhaipuhong.com
  11. Message-ID:<11627000.01215604718796.JavaMail.db2admin@ZPH>
  12. Subject:Ihavamyownmailserver
  13. MIME-Version:1.0
  14. Content-Type:text/plain;charset=us-ascii
  15. Content-Transfer-Encoding:7bit
  16. Fromnow,youhaveyourownmailserver,congratulation!

 

 

 

 

从上面的结果可以看出,该邮件是由zhaipuhong@zhaipuhong.com发给 zph@zhaipuhong.com 的。

 

多发几封电子邮件,就会发现,James 的邮件接收是一个栈结构,最近收到的邮件编号为0,依次类推……

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics