电子邮件服务器(如sina,sohu,163等),相当于现实中的邮局。主要提供以下功能:

1.接收用户投递的邮件

2.将用户投递的邮件转发给其它邮件服务器

3.接收其它邮件服务器发来的邮件并将邮件存储到其管理的用户邮中

4.为前来取邮件的用户提供邮件读取服务

 

 

邮件服务器按通讯协议可以划分为两种类型

SMTP服务器:用于替用户发送邮件和接收外面发送给本地用户的邮件,它相当于现实生活中邮件的邮件接收部门(可以接收普通用户投递的邮件,也可以接收其它邮局投递过来的邮件)

POP3/IMAP服务器:用于帮助用户读取SMTP服务器接收进来的该用户的邮件。

电子邮箱:每个电子邮件服务器之上都可以开设多个电子邮箱,电子邮箱也称之为e-mail地址,它类似于现实生活中的通讯地址,用户可以通过此地址接收别人发来的电子邮件和向别人发送电子邮件。电子邮箱就是在它所属的邮件服务器上申请的一个帐户,邮件服务器为这个帐户分配的邮箱空间,用户通过用户名和密码登录到服务器来查收该地址已收到的邮件。

 

邮件客户端软件:邮件客户端软件负责与邮件服务器通讯,主要用于帮助用户将用户发送给SMTP服务器和从POP3/IMAP邮件服务器读取用户的电子邮件。邮件客户端软件通常集邮件编写、发送和接收功能于一体。比如:Foxmail、Outlook Express。

wKiom1Vpbarj7qW3AAF28ozovhI995.jpg

结合上图简述过程:

步骤一,投递邮件:zhangsan通过客户端软件,使用SMTP协议,把邮件投递到新浪的SMTP服务器

步骤二,服务器发送:新浪SMTP服务器,使用SMTP协议,把邮件发送到sohu的SMTP服务器上

步骤三,服务器收取:sohu的SMTP服务器把邮件放到邮箱帐户对应的存储空间中。

步骤四,用户收取:当lisi通过客户端软件登录时,询问是否有邮件时,sohu的POP3服务器会到lisi这个帐户所对应的存储空间查找邮件。


 

SMTP服务器的监听端口:25

POP3服务器的监听端口:110

 

SMTP协议命令:

Ehlo :SMTP邮件发送程序与SMTP邮件接收程序建立连接后必须发送的第一条命令。参数表示SMTP服务器发送者的主机名,ehlo命令用于替代传统SMTP协议的helo命令

Auth:如果SMTP邮件接收程序需要SMTP邮件发送程序进行认证时,它会向SMTP邮件发送程序提示它所采用的认证方式,SMTP邮件发送程序接着应该使用这个命令回应SMTP邮件接收程序,参数表示回应认证的方式。

Mail from:此命令用于指定邮件发送者邮箱地址,参数表示发件人的邮箱地址。

Rcpt to :此命令用于指定邮件接收者的邮箱地址,参数表示接收者的邮箱地址,如果要发送给多个接收者,则要使用多条Rcpt to 命令来分别指定每一个接收者的邮箱地址。

Data:此命令用于表示SMTP邮件发送程序准备开始传递邮件内容,在这个命令后面发送的所有数据都将被当作邮件内容,直到遇到.(点号)标识符,则表邮件内容结束。

Data下的内容:from、to、subject、date。


 

SMTP服务器如何识别普通用户或邮件服务器:

wKioL1Vpb4PTp1JDAAG6s-SD_E0280.jpg

邮件服务提供商只需要将供其它SMTP服务器访问的SMTP服务器添加到DNS系统的MX记录中,其它邮件就可以通过DNS解析访问。 但是不能将供邮件客户端软件访问的邮件服务器添加到DNS系统的MX记录中,否则,其他邮件服务器检索MX记录时将会得到这些专供给邮件客户端访问的SMTP服务器,而这些邮件服务器是要求登录验证得。上图重点展示了邮件服务器与邮件服务器之间的邮件收发过程:

结合上图,说明邮件服务器如何识别普通用户、邮件服务器。普通用户访问时,会根据邮件服务器提供的邮件服务收发地址进行访问(比如sina提供给普通用户的sm3p,.sina.com和pop.sina.com). 而邮件服务器访问访问邮件服务时,会根据MX记录进行dns解析,找到注册到DNS系统中的MX记录,相当于进行的是一个反向解析的过程。

要自己写程序发送和接收邮件,可以直接采用Socket编程连接上远程的邮件服务器,然后按照邮件协议与邮件服务器进行交互,这其中涉及很多细节,而且如果要创建出MIME格式的邮件,也相当繁琐的事。


Sun公司为了方便开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持常用的邮件协议,如SMTP、POP3、IMAP。 开发人员使用javaMail API编写邮件处理软件时,无须考虑邮件协议的底层实施细节,只要调用javaMail开发包中相应的API即可。同时,javaMail开发包还提供了能够创建出各种复杂MIME格式的邮件API

JavaMai开发包大致可以划分为如下四类:

(1)创建和解析邮件内容的API:Message是创建和解析邮件的核心API,它的实例对象代表一封电子邮件

(2) 发送邮件API:Transport类是发送邮件的核心API,它的实例对象代表了实现某个邮件发送协议(SMTP协议)的邮件发送对象。

(3)接收邮件API:Store类是接收邮件的核心API,它的实例对象代表实现了某个邮件接收协议(如POP3协议)的邮件接收对象。

(4)环境:Session类用于定义整个应用程序所需的环境信息,以及收集客户端与邮件服务器建立网络连接的会话信息,如邮件服务器主机名,商品号,采用邮件发送和接收协议等。Session对象会把设置的环境信息作为参数传递给Message构造器。

JAF:JavaBeans Activation Frameword,javaBeas激活框架,专用于数据处理框架,它用于封装数据,并为应用程序访问和操作数据提供接口。

JAF的主要作用在于让Java应用程序知道如何对一个数据源进行查看、编辑和打印等操作。对于通过JAF封装的数据,应用程序通过JAF接口可以完成如下功能:

访问数据源中的数据、获知数据源的数据类型、获知可对数据进行的各种操作、用户执行某种操作时,自动创建执行该操作的软件部件的实例对象。

JavaMail api 可以利用JAF从某种数据源中读取数据和获知数据的MIME类型,并用这些数据生成MIME消息中的消息体和消息类型。

JAF在jdk1.6后自动带有,对应于javax.activation包。主要在创建邮件时使用此jar包。如果JDK版本低于1.6,需要下载activation.jar包

 

 

自带项目说明:(学习时的两个项目)

javaMail 项目:这是一个java Project项目,有三个java类,Base是基本的邮件接收程序,在此程序中展示了两种方式收邮件。关于Base.java类有三点需要强调:

1.Session对象:通过Session类的静态方法getDefaultInstance每一次返回的都是同一个Session对象(在第一次调用此方法后得到一个Session对象并保存起来,第二次调用时,直接返回保存的Session对象),如果想依赖此方法返回的Session对象进行邮件收和发两个操作,将会出错。getInstance每次返回的都是一个新的Session对象,因此要同时进行收发操作,可以使用此方法。Session对象依赖Property对象必须设置的两个属性:

props.setProperty("mail.smtp.auth", "true");

props.setProperty("mail.transport.protocol", "smtp");

2.验证机制:我们可以在创建Session时,指定用户名与密码。也可以在发送邮件时,先让Transport对象调用connect方法指定(此方法实质是Transport父类Service中的一个方法)

3.发送机制:可以直接让Transport类调用静态的send发送,也可以让Transport对象调用静态方法或者抽象的sendMessage方法

 

StepDemo.java:

此类主要是用于创建一封eml格式的邮件:其中难点在于理清邮件的结构层次关系。另外此程序还展示了如下几个小技巧:显示发件人的友好名称、邮件的真正回复地址(并不是默认回复给发件人)、附件名称中方乱码处理。

 

StepDemo2.java:

主要把StepDemo创建的eml格式的邮件进行封装,使之成为一个Message对象。封装代码:

FileInputStream fis = new FileInputStream("G:/java邮件开发/java生成.eml");

Message msg = new MimeMessage(session, fis);

 

JavaMailWeb项目:这是一个web项目,主要演示了Servlet处理邮件发送思路。

需要说明以下几点:

Tomcat服务器并不带有mail包,所以在项目下应导入mail.jar包。

如果使用想使用JNDI技术创建一个Session对象,需要注意以下几点:

JNDI创建Session是tomcat完成,因此需要在tomcat的lib目录下导入mail.jar。

但是如果在当前项目下同时存在mail.jar包。将会出错:通过JNDI获取的Session对象将不能转成当前项目类中定义的Session对象,只个主要是因为类装载器引发的问题,涉及的是类的装载问题,目前我还不是很清楚(作记号),不在此多作说明。

关于邮件开发的更多细节,建议研究mail.jar开发包自带的文档实例