使用JAMES & JavaMail搭建邮件系统

使用JAMES & JavaMail搭建邮件系统

一、简介

Apache JamesJava Apache Mail Enterprise Server)是Apache组织的子项目之一,完全采用纯Java技术开发,实现了SMTPPOP3NNTP等多种邮件相关协议。

James也是一个邮件应用平台,可以通过Mailet扩充其功能,如Mail2SMSMail2Fax等。James提供了比较完善的配置方案,尤其是关于邮件内容存储和用户信息存储部分,可以选择在文件、数据库或其他介质中保存。

James性能稳定、可配置性强,还是开源项目,所有源代码不存在版权问题,因此,James在项目中的应用日益广泛,现在常用版本为2.1,但最新版本2.3已经推出,在本文中,我们将仍以James2.1作为介绍蓝本。

二、安装与配置

James的安装配置过程非常简单。

第一步:安装JDK

请使用JDK1.3以上版本(推荐使用JDK1.4),假设安装在c:/jdk1.3

第二步:下载James,并解压

可以到Apache网站上下载James2.1,下载将得到一个压缩文件james-2.1.zip,大小为4.45M,将此包解压到c:/james

第三步:直接运行或需要配置JAVA_HOME

这时,可以尝试直接双击c:/james/bin/run.bat,若启动无误,将提示如下:

Using PHOENIX_HOME:   C:/james
Using PHOENIX_TMPDIR: C:/james/temp
Using JAVA_HOME:
 
Phoenix 4.0.1
 
James 2.1
Remote Manager Service started plain:4555
POP3 Service started plain:110
SMTP Service started plain:25
NNTP Service Disabled
Fetch POP Disabled

也有可能启动不了,并报JAVA_HOME找不到,这时,需要指定JAVA_HOME,比较简单的方法是在c:/james/bin/run.bat中指定JAVA_HOME,修改后的run.bat如下:

……
rem
rem Determine if JAVA_HOME is set and if so then use it
rem
set JAVA_HOME= c:/jdk1.3
if not "%JAVA_HOME%"=="" goto found_java
……

三、项目应用

某单位,有16个职能处室,共78台电脑(操作系统为Win98/2000/xp),其中有1台为专用服务器(Win2000),已连成局域网。为使单位内部的信息交流,尤其是文件交互更加便捷,单位决定在局域网内部架设一套E-mail系统。

1、解决方案

在专用服务器上安装James2.1,客户端使用操作系统自带的Outlook Express

1)、服务器端配置

首先找出专用服务器的名字,假设叫unitname

然后打开文件c:/james/apps/james/SAR-INF/config.xml

config.xml文件中,找到<postmaster>Postmaster@localhost</postmaster>,把此项改为<postmaster>Postmaster@unitname</postmaster>,同理,找到<servername>localhost</servername>,把此项改为<servername>unitname</servername>。其实,改这两项就是把默认的localhost改为机器名,这样做是为了让其它机器也能访问邮件系统,当然,前提是在局域网上没有与服务器重名的机器。

2)、客户端配置

假设有一个账号,用户名为holen,密码为123456,如何在Outlook中配置呢?

首先,根据用户名,可以得出该用户邮箱地址为holen@unitname ,然后在输入POP3SMTP服务器时,直接使用服务器机器名unitname即可。

3)、用Telnet管理用户

  用cmd进入MS-DOS,输入telnet localhost 4555 (注:localhost是邮件服务器名,4555是管理端口,可在/apps/james/SAR-INF/config.xml文件中配置,在此我们使用其默认配置)
  然后输入用户名和密码(在配置文件config.xml中,默认为用户名:root密码:
root)
出现如下信息说明登陆成功:

<administrator_accounts>节中可以修改默认帐户密码

remotemanager中可以修改登陆端口

 

postmaster中可以修改邮箱域名

登陆成功后,我们就可以开始对用户信息进行增、删、查、改等操作了。
常用的用户信息操作命令参见下表:

Currently implemented commands:                  常用实现命令

help                display this help            显示帮助信息

listusers           display existing accounts    显示现有账户

countusers          display the number of existing accounts 显示现有账户数量

adduser [username] [password]   add a new user   添加一个新用户

verify [username]   verify if specified user exist  核实指定用户是否存在

deluser [username]   delete existing user        删除存在的用户

setpassword [username] [password]   sets a user's password  设置用户密码

setalias [user] [alias]   locally forwards all email for 'user' to 'alias' 设置邮箱别名

showalias [username]   shows a user's current email alias 显示别名

unsetalias [user]     unsets an alias for 'user'    删除用户别名

setforwarding [username] [emailaddress]   forwards a user's email to another email address      转发用户的电子邮件地址到另一个电子邮件地址

showforwarding [username] shows a user's current email forwarding 显示用户的当前邮件转发

unsetforwarding [username]     removes a forward         删除转发

user [repositoryname]    change to another user repository   改变另一个用户库

shutdown kills the current JVM (convenient when James is run as a daemon)  关闭当前的服务

quit                close connection              关闭连接

4)、Java Mail

1.包准备:mail.jaractivation.jar

2.发送邮件需要做如下一些事情:

配置邮件服务器属性信息,

配置邮件接收地址,

使用SMTP认证获得会话(Session),

构建邮件体(MimeMessage),

发送邮件。

5)、Message存储结构

Message是邮件发送的最终对象,我们一般使用他的子类对象MimeMessage,其子类对象里包含有邮件的MessageIDSubjectFlagFromSenderContent等信息,Content是邮件的内容体,其一般是一个Multipart对象(或其子类对象MimeMultipart),所有的邮件内容都存在于Multipart中的。一个Multipart包含有一个或多个BodyPart对象(或其子类对象MimeBodyPart),BodyPart对象用于存储邮件的内容,可以是文本形式,也可以是附件形式。

6)、Session

Session类定义了一个基本邮件会话,它是Javamail API最高层入口类,所有其它类都必须经由Session对象才得以生效。Session对象管理配置选项和用于与邮件系统交互的用户认证信息,它使用java.util.Properties对象获取信息,如邮件服务器、用户名、密码及整个应用程序中共享的其它信息。
  Session类的构造器是私有的,它不能被继承,也不能使用new语句来创建实例,但它提供了两个表态方法getInstancegetDefaultInstance来获取Session实例,前者创建一个独立的会话,否则获取缺省的共享会话。

7)、Address

Address类表示电子邮件地址,它是一个抽象类。其子类(最经常使用的子类是javax.mail.internet.InternetAddress)提供具体实现,且通常可串行化。
在创建了SessionMessage,并设置了消息内容后,可以用Address确定邮件消息的发送者和接收者地址。

8)、Authenticator

Authenticator代表一个可以为网络连接获取认证信息的对象,它通常通过提示用户输入用户名和密码来收集认证信息,使连接可以访问受保护的资源。对于Javamail API来说,这些资源就是邮件服务器。Javamail Authenticatorjavax.mail包中,它和java.net中同名的类Authenticator不同。
  要使用Authenticator,必须先创建一个它的子类实例,并且在会话对象创建时为会话注册该Authenticator对象。在需要认证的时候,就会通知Authenticator。程序可以弹出窗口,也可以从配置文件中(虽然没有加密是不安全的)读取用户名和密码,并使用它们作为构造函数参数创建一个PasswordAuthentication对象返回给调用程序。

9)、Transport

javax.mail.Transport
  消息发送的最后步骤是使用Transport类。该类使用指定协议发送消息(通常是SMTP)。Transport是抽象类,它的工作方式与Session有些类似,可以通过静态方法或实例方法发送消息。Transport继承自Service类,而后者提供了很多通用方法,如命名传输、连接服务器、监听传输事件等等。

10)、Store

javax.mail.Store
  Store是一个抽象类,它模拟了消息存储器及其内部目录(Folder)访问协议,以存储和读取消息,其子类提供具体实现。

  Store定义的存储器包括一个分层的目录体系,消息存储在目录内,。客户程序可以通过获取一个实现了数据库访问协议的Store对象来访问消息存储器,绝大多数存储器要求用户在访问前提供认证信息,connect方法执行了该认证过程。

  Store store = session.getStore("pop3");//指定协议

  store.connect(host,usename,password);//

11)、.Folder

javax.mail.Folder
  Folder是一个抽象类,用于分级组织邮件,其子类提供针对具体协议的实现。Folder代表的目录可以容纳消息或子目录,存储在目录内的消息被顺序计数(从1开始到消息总数),该顺序被称为邮箱顺序,通常基于邮件消息到达目录的顺序。邮件顺序的变动将改变消息的序列号,这种情况仅发生在客户程序调用Expunge方法擦除目录内设置了Flags.Flag.DELETED标志位的消息时。执行擦除操作后,目录内消息将重新编号。

  客户程序可以通过消息序列号或直接通过相应的Message对象应用目录中的消息,由于消息序列号在会话中很可能改变,因此应尽可能保存Message对象而非序列号来反复引用对象。

  连接到Store之后,接下来可以获取一个文件夹(Folder)。该文件夹必须先使用open()方法打开,然后才能读取里面的消息:

Folder folder = store.getDefaultFolder();
//
: Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_WRITE);
Message message[] = folder.getMessage();
  open()方法指定了要打开的文件夹及打开方式(如Folder.READ_WRITE)。 inboxPOP3唯一可以使用的文件夹。如果使用IMAP,还可以用其它的文件夹。获得Message之后,就可以用getContent()获得其内容,或者用writeTo()将内容写入输出流。getContent()方法之能得到消息内容,而writeTo()的输出却包含消息头.读完邮件之后要关闭与FolderStore的连接:

folder.close(aBoolean);
store.close();

2、发送核心代码

第一步,设置系统的一系列属性

Properties props = System.getProperties();

props.put("mail.smtp.host", mailServer);

第二步,取得一个Session对象,代表一次发送会话

Session sendmailsession = Session.getDefaultInstance(props, null);

第三步 ,得到一个实际发送邮件的信息对象

MimeMessage message = new MimeMessage(sendmailsession);

第四步,得到一个用于发送邮件的类,指定发送的协议

Transport transport = sendmailsession.getTransport("smtp");

/* 以下是服务器需要认证时所要的方法 */

transport.connect(mailServer, name, password);

transport.sendMessage(message, message.getAllRecipients());

transport.close();

 

注意:发送邮件要指定发件人密码, 接受邮件需要接受人的密码

1)、接受邮件

获取系统的属性对象

Properties props = System.getProperties();

// 指定邮件服务器的名称

props.put("mail.smtp.host", mailServer);

// 指定邮件服务器接收邮件的协议

props.put("mail.store.protocol", "pop3");

取得一个Session对象,代表一个邮件会话

Session savemailsession = Session.getDefaultInstance(props, null);

得到一个邮件对象

Store store = savemailsession.getStore("pop3");

// 根据用户名和密码连接上指定邮箱地址

store.connect(mailServer, name, password);

// 得到一个邮件夹

Folder folder = store.getFolder("INBOX");

// 指定访问的能力

folder.open(Folder.READ_WRITE);

读邮件

关闭邮件夹和邮箱

folder.close(true);

store.close();

2)、SendEmail

Properties pro = System.getProperties();

pro.setProperty("mail.smtp.host", server);

Session sendsession = Session.getDefaultInstance(pro, null);

MimeMessage message = new MimeMessage(sendsession);

message.setSubject(subject, "gbk");

message.setText(context, "gbk");

message.setSentDate(new Date());

message.setFrom(new InternetAddress(from));

message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

//认证

Transport tran =  sendsession.getTransport("smtp");

tran.connect(server, uname, upwd);

tran.sendMessage(message, message.getAllRecipients());

tran.close();

3)、GetEmail

Properties pro = System.getProperties();

pro.setProperty("mail.smtp.host", server);

pro.setProperty("mail.store.protocol", "pop3");

Session session = Session.getDefaultInstance(pro, null);

Store store= session.getStore("pop3");

store.connect(server, uname, upwd);

Folder foler = store.getFolder("inbox");

foler.open(Folder.READ_WRITE);

int total = foler.getUnreadMessageCount();

System.out.println("未读邮件数:"+total);

int newemail = foler.getNewMessageCount();

System.out.println("新邮件数:"+total);

Message[] message = foler.getMessages();

for(Message m: message){

System.out.println("主题:"+m.getSubject()+" 正文:"+m.getContent());

m.setFlag(Flags.Flag.DELETED, true);

}

foler.close(true);

store.close();

略有分享,不足之处,还望指正!!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值