《Maven實戰》與本地郵件服務器

並不是在研究郵件服務器實現,這兩天學習用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

我此次使用的安裝包是james 2.3.2你們能夠從這裏下載到。api

如今讓咱們開始咱們激動人心的james之旅。首先咱們將james-binary-2.3.2.zip解壓縮到你的安裝目錄。咱們能夠把這個過程理解爲安裝的過程。我在這裏將它解壓到D:\.這樣咱們的james就安裝好了。目錄爲D:\james-2.3.2tomcat

準備知識 - 學習一些必要的知識

在我使用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);
  }
}

實現-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.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。

Mailet的實現

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研究透了。之後我可能會寫一篇相關的文章,在這就很少說了。但願這篇文章可以對你們有所啓發!有所幫助!祝你們工做順利!

相關文章
相關標籤/搜索