• 用JAMES实现自己的邮件服务器


    James 是一个企业级的邮件服务器,它完全实现了smtp 和 pops 以及nntp 协议。同时,james服务器又是一个邮件应用程序平台。James的核心是Mailet API,而james 服务齐是一个mailet的容器。它可以让你非常容易的实现出很强大的邮件应用程序。James开源项目被广泛的应用于与邮件有关的项目中。你可以通过它来搭建自己的邮件服务器。我们可以利用Mailet API,编程接口来实现自己所需的业务。James集成了Avalon 应用程序框架以及Phoenix Avalon 框架容器。Phoenixjames 服务器提供了强大的支持。需要说明的是Avalon开源项目目前已经关闭。
       我这次使用的安装包是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.batrun.shJames的启动程序。只要记住这个重要文件就可以。
    启动之后控制台显示如下:
    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.xmljames中的核心配置文件。
    Logs 包含了与james有关的Log。调试全靠它了。
    Var 包含了一些文件夹通过它们的名字我们大概也能猜测出它们的用途。Mail主要用于存储邮件。nntp主要用于新闻服务器。Users用于存储所有邮件服务器的用户。也就是邮件地址前面的东东。如:pig@sina.compig就是所谓用用户。
     
    创建用户:
     我们在James上建若干用户,用来测试收发邮件。当然如果你不用james本身的用户也可以。Jamestelnet 的方式提供了接口用来添加用户。下面我来演示一下。
    首先使用telnet来连接jamesremote 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就相当于一个matchermailet的容器。就像tomcat之于servlet。而mailetservlet很是相似。
         我们这里要完成的功能很简单,就是当james邮件服务器接收到鸣人(人名)后把发送者和邮件正文打印到控制台。我们分析这个需求发现我们需要写一个matcher以及一个mailet.matcher用来过滤而mailet用来将邮件内容打印到控制台。为了简单起见,我这次只是继承了GenericMailet GenericRecipientMatcher 两个已经实现的 mailet matcher.具体的MatcherMailet的使用我以后会整理成另外一篇文章。
     
    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.xmljames/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研究透了。以后我可能会写一篇相关的文章,在这就不多说了。希望这篇文章能够对大家有所启发!有所帮助!祝大家工作顺利!
  • 相关阅读:
    Excel与Google Sheets中实现线性规划求解
    Optaplanner终于支持多线程并行运行
    【译】Optaplanner开发手册本地化: (0)
    多工序、多机台(产线)环境下的排程要点
    设计Optaplanner下实时规划服务的失败经历
    Optaplanner规划引擎的工作原理及简单示例(2)
    vim 分屏
    vim autocmd
    irun vcs option
    记录
  • 原文地址:https://www.cnblogs.com/liaomin416100569/p/9331709.html
Copyright © 2020-2023  润新知