JavaMail实现收发邮件——(一)相关概念概述

简介:

一、JavaMail概述:

       JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类。但它并没有包含在JDK中,而是作为JavaEE的一部分。

       厂商所提供的JavaMail服务程序可以有选择地实现某些邮件协议,常见的邮件协议包括:

l         SMTP:简单邮件传输协议,用于发送电子邮件的传输协议;

l         POP3:用于接收电子邮件的标准协议;

l         IMAP:互联网消息协议,是POP3的替代协议。

这三种协议都有对应SSL加密传输的协议,分别是SMTPSPOP3SIMAPS

JavaMail服务提供程序之外,JavaMail还需要JAF(JavaBeans Activation Framework)来处理不是纯文本的邮件内容,这包括MIME(多用途互联网邮件扩展)、URL页面和文件附件等内容。


二、对相关协议的回顾:

       1、介绍

       在研究 JavaMail API 的细则之前,让我们回顾用于 API 的协议。基本上,您会逐渐熟悉并喜爱的协议有四个:

    * SMTP

    * POP

    * IMAP

    * MIME

 

您还将碰到 NNTP 和其它协议。理解所有协议的基本知识将有助于您理解如何使用 JavaMail API。虽然不了解这些协议您照样可以用这个 API,却不能够克服那些基础协议的局限性。如果我们精选的协议不能支持某种性能,JavaMail API 决不能魔术般的将这种性能添加上去。(您很快就会看到,在处理 POP 时这将成为一个难题。)

      

       2SMTP

       简单邮件传输协议(Simple Mail Transfer ProtocolSMTP)由 RFC 821 定义。它定义了发送电子邮件的机制。在JavaMail API 环境中,您基于 JavaMail 的程序将和您的公司或因特网服务供应商的(Internet Service Provider'sISP'sSMTP服务器通信。SMTP 服务器会中转消息给接收方 SMTP 服务器以便最终让用户经由 POP  IMAP 获得。这不是要求 SMTP 服务器成为开放的中继,尽管 SMTP 服务器支持身份验证,不过还是得确保它的配置正确。像配置服务器来中继消息或添加删除邮件账号这类任务的实现,JavaMail API 中并不支持。

 

       3POP

       POP 代表邮局协议(Post Office Protocol)。目前用的是版本 3,也称 POP3RFC 1939 定义了这个协议。POP 是一种机制,因特网上大多数人用它得到邮件。它规定每个用户一个邮箱的支持。这就是它所能做的,而这也造成了许多混淆。使用POP 时,用户熟悉的许多性能并不是由 POP 协议支持的,如查看有几封新邮件消息这一性能。这些性能内建于如 Eudora Microsoft Outlook 之类的程序中,它们能记住一些事,诸如最近一次收到的邮件,还能计算出有多少是新的。所以当使用JavaMail API 时,如果您想要这类信息,您就必须自己算。

 

       4IMAP

       IMAP 是更高级的用于接收消息的协议。在 RFC 2060 中被定义,IMAP 代表因特网消息访问协议(Internet Message Access Protocol),目前用的是版本 4,也称 IMAP4。在用到 IMAP 时,邮件服务器必需支持这个协议。不能仅仅把使用POP 的程序用于 IMAP,并指望它支持 IMAP 所有性能。假设邮件服务器支持 IMAP,基于 JavaMail 的程序可以利用这种情况  用户在服务器上有多个文件夹(folder),并且这些文件夹可以被多个用户共享。

       因为有这一更高级的性能,您也许会认为所有用户都会使用 IMAP。事实并不是这样。要求服务器接收新消息,在用户请求时发送到用户手中,还要在每个用户的多个文件夹中维护消息。这样虽然能将消息集中备份,但随着用户长期的邮件夹越来越大,到磁盘空间耗尽时,每个用户都会受到损失。使用 POP,就能卸载邮件服务器上保存的消息了。

      

       5MIME

       MIME 代表多用途因特网邮件扩展标准(Multipurpose Internet Mail Extensions)。它不是邮件传输协议。但对传输内容的消息、附件及其它的内容定义了格式。这里有很多不同的有效文档:RFC 822RFC 2045RFC 2046  RFC 2047。作为一个JavaMail API 的用户,您通常不必对这些格式操心。无论如何,一定存在这些格式而且程序会用到它。

 

       6NNTP及其他

       因为 JavaMail API 将供应商和所有其它的东西分开了,您就能轻松添加额外的协议支持。Sun 保留了一张第三方供应商列表,他们利用了 Sun 不提供超出(out-of-the-box)支持范围的协议。您会找到 NNTP(网络新闻传输协议)[新闻组]S/MIME(安全多用途因特网邮件扩展)及其它支持。


三、JavaMail的关键对象:

Properties:属性对象

       由于JavaMail需要和邮件服务器进行通信,这就要求程序提供许多诸如服务器地址、端口、用户名、密码等信息,JavaMail通过Properties对象封装这些属性西信息。如下面的代码封装了两个属性信息:

       Properties props = new Properties();

    props.put("mail.smtp.host""smtp.sina.com.cn");

    props.put("mail.smtp.auth""true");

   

    针对不同的的邮件协议,JavaMail规定了服务提供者必须支持一系列属性,下表是针对SMTP协议的一些常见属性(属性值

都以String类型进行设置,属性类型栏仅表示属性是如何被解析的):

属性名 属性类型 说明
mail.stmp.host String SMTP服务器地址,如smtp.sina.com.cn
mail.stmp.port int SMTP服务器端口号,默认为25
mail.stmp.auth boolean SMTP服务器是否需要用户认证,默认为false
mail.stmp.user String SMTP默认的登陆用户名
mail.stmp.from String 默认的邮件发送源地址
mail.stmp.socketFactory.class String socket工厂类类名,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.net.SocketFactory接口
mail.stmp.socketFactory.port int 指定socket工厂类所用的端口号,如果没有规定,则使用默认的端口号
mail.smtp.socketFactory.fallback boolean 设置为true时,当使用指定的socket类创建socket失败后,将使用java.net.Socket创建socket,默认为true
mail.stmp.timeout int I/O连接超时时间,单位为毫秒,默认为永不超时

    其他几个协议也有类似的一系列属性,如POP3mail.pop3.hostmail.pop3.port以及IMAPmail.imap.hostmail.imap.port等。更详细的信息请查看com.sun.mail.smtpcom.sun.mail.pop3com.sun.mail.imap这三个包的Javadochttp://java.sun.com/products/javamail/javadocs/index.html


Session:会话对象

       Session是一个很容易被误解的类,这归咎于混淆视听的类名。千万不要以为这里的SessionHttpSession一样代表真实的交互会话,但创建Session对象时,并没有对应的物理连接,它只不过是一对配置信息的集合。Session的主要作用包括两个方面:

       1)接收各种配置属性信息:通过Properties对象设置的属性信息;

       2)初始化JavaMail环境:根据JavaMail的配置文件,初始化JavaMail环境,以便通过Session对象创建其他重要类的实例。


TransportStore:传输和存储

       邮件操作只有发送或接收两种处理方式,JavaMail将这两种不同操作描述为传输(javax.mail.Transport)和存储(javax.mail.Store),传输对应邮件的发送,而存储对应邮件的接收。

       Session提供了几个用于创建TransportStore实例的方法,在具体讲解这些方法之前,我们事先了解一下Session创建TransportStore的内部机制。我们知道提供者在javamail.providers配置文件中为每一种支持的邮件协议定义了实现类,Session根据协议类型(stmppop3等)和邮件操作方式(传输和存储)这两个信息就可以定位到一个实例类上。比如,指定stmp协议和transport类型后,Session就会使用com.sun.mail.smtp.SMTPTransport实现类创建一个Transport实例,而指定pop3协议和store类型时,则会使用com.sun.mail.pop3.POP3Store实例类创建一个Store实例。Session提供了多个重载的getTransport()getStore()方法,这些方法将根据SessionProperties属性设置情况进行工作,影响这两套方法工作的属性包括:

属性名 说明
mail.transport.protocol 默认的邮件传输协议,例如,smtp
mail.store.protocol 默认的存储邮件协议,例如:pop3
mail.host 默认的邮件服务地址,例如:192.168.67.1
mail.user 默认的登陆用户名,例如:zapldy

下面,我们再回头来了解SessiongetTransport()getStore()的重载方法。

l         Transport getTransport():当Session实例设置了mail.transport.protocol属性时,该方法返回对应的Transport实例,否则抛出javax.mail.NoSuchProviderException

l         Transport getTransport(String protocol):如果Session没有设置mail.transport.protocol属性,可以通过该方法返回指定类型的Transport,如transport = session.getTransport(“smtp”)

Message:消息对象

       一旦获得 Session 对象,就可以继续创建要发送的消息。这由 Message 类来完成。因为 Message 是个抽象类,您必需用一个子类,多数情况下为 javax.mail.internet.MimeMessageMimeMessage 是个能理解 MIME 类型和头的电子邮件消息,正如不同 RFC 中所定义的。虽然在某些头部域非 ASCII 字符也能被译码,但 Message 头只能被限制为用 US-ASCII 字符。

 

要创建一个 Message,请将 Session 对象传递给 MimeMessage 构造器:

MimeMessage message = new MimeMessage(session);


Address:地址

       一旦您创建了 Session  Message,并将内容填入消息后,就可以用 Address 确定信件地址了。和 Message 一样,Address 也是个抽象类。您用的是 javax.mail.internet.InternetAddress 类。

若创建的地址只包含电子邮件地址,只要传递电子邮件地址到构造器就行了。

Address address = new InternetAddress("president@whitehouse.gov");

若希望名字紧挨着电子邮件显示,也可以把它传递给构造器:

Address address = new InternetAddress("president@whitehouse.gov", "George Bush");

需要为消息的 from 域和 to 域创建地址对象。除非邮件服务器阻止,没什么能阻止你发送一段看上去是来自任何人的消息。

一旦创建了 address(地址),将它们与消息连接的方法有两种。如果要识别发件人,您可以用 setFrom()  setReplyTo() 方法。

message.setFrom(address)

需要消息显示多个 from 地址,可以使用 addFrom() 方法:

Address address[] = ...;

message.addFrom(address);

若要识别消息 recipient(收件人),您可以使用 addRecipient() 方法。除 address(地址)外,这一方法还请求一个Message.RecipientType

message.addRecipient(type, address)

三种预定义的地址类型是:

Message.RecipientType.TO        代表有健的主要接收者。

Message.RecipientType.CC        代表有健的抄送接收者。

Message.RecipientType.BCC     代表邮件的暗送接收者。


Authenticator:认证者

        java.net 类一样,JavaMail API 也可以利用 Authenticator 通过用户名和密码访问受保护的资源。对于JavaMail API 来说,这些资源就是邮件服务器。JavaMail Authenticator  javax.mail 包中,而且它和 java.net 中同名的类 Authenticator 不同。两者并不共享同一个 Authenticator,因为JavaMail API 用于 Java 1.1,它没有 java.net 类别。

       要使用 Authenticator,先创建一个抽象类的子类,并从 getPasswordAuthentication() 方法中返回 PasswordAuthentication实例。创建完成后,您必需向 session 注册 Authenticator。然后,在需要认证的时候,就会通知 Authenticator。您可以弹出窗口,也可以从配置文件中(虽然没有加密是不安全的)读取用户名和密码,将它们作为 PasswordAuthentication 对象返回给调用程序。

Properties props = new Properties();

// fill props with any information

Authenticator auth = new MyAuthenticator();

Session session = Session.getDefaultInstance(props, auth);




本文转自 pangfc 51CTO博客,原文链接:http://blog.51cto.com/983836259/1664173,如需转载请自行联系原作者

相关文章
|
自然语言处理 算法 数据安全/隐私保护
教你如何用代码自动群发邮件(邮件轰炸机)
教你如何用代码自动群发邮件(邮件轰炸机)
1177 0
教你如何用代码自动群发邮件(邮件轰炸机)
|
Java
Java Email邮件阿里云发不了怎么处理
最近升级了一下SpringBoot的版本,结果发现之前工作的好好的邮件突然罢工了,罢工的原因还不止一个,接下来记录一下解决方案
423 0
|
8月前
|
Java Maven
Java实现163网易邮箱消息发送
Java实现163网易邮箱消息发送
128 0
|
Java 数据安全/隐私保护
springboot发邮件,javaxmail收邮件功能
springboot发邮件,javaxmail收邮件功能
216 0
|
Java 数据安全/隐私保护 Spring
如何使用JavaMailSender给曾经心爱的她发送一封特别的邮件
如何使用JavaMailSender给曾经心爱的她发送一封特别的邮件
229 0
如何使用JavaMailSender给曾经心爱的她发送一封特别的邮件
|
人工智能 Java 机器人
编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)
编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)
246 0
编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)
|
Java
【知识积累】JavaMail实现发邮件功能
今天闲来没事,想着通过程序来给别人发邮件。于是,上网搜了一下,相应的资料也很多,刚开始完成了邮件的简单发送,后来想如何能发送附件,继续寻找 答案,但是遇到了一个问题是当我使用txt类型作为附件时,附件里的内容总是会显示在正文里面,并且还会出现正文乱码的现象,之后经过不断的查阅资料,终 于解决了问题,实现了我自己想要的功能。
86 0
|
Java
springboot业务功能实战(二十)连接内外网邮箱配置全解析,实现邮件提醒功能
springboot业务功能实战(二十)连接内外网邮箱配置全解析,实现邮件提醒功能
306 0
springboot业务功能实战(二十)连接内外网邮箱配置全解析,实现邮件提醒功能