用JAMES实现自己的邮件服务器 (二)

快速上手
安装james
   我这次使用的安装包是james 2.3.1。大家可以从这里下载到http://james.apache.org/download.cgi
 现在让我们开始我们激动人心的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
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用于存储所有邮件服务器的用户。也就是邮件地址前面的东东。如:[email protected]的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监测到这封邮件,并且调用相应的mailet来进行处理。由mailet打印出相应的邮件发送者和正文。运行Mail类后得到
Using PHOENIX_HOME:   C:/james
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研究透了。

猜你喜欢

转载自blog.csdn.net/mengzengyun1983/article/details/4663147