java mail 学习笔记

JAVA MAIL 学习 笔记

电子邮件协议的简介

SMTP 简单邮件传输

SMTP是Simple Mail Transfer Protocol的简称,即简单邮件传输协议。该协议定义了邮件客户端软件和SMTP服务器之间,以及两台SMTP服务器之间的通信规则。在Java Mail API中,基于Java Mail的程序将与本公司或Internet服务提供商(ISP)的SMTP服务器通信,该SMTP服务器将会把消息转发给用于接收消息的SMTP服务器,最后用户可通过POP或IMAP协议获取该消息。由于支持身份验证,所以不需要SMTP服务器是一种开放的转发器,但需要确保SMTP服务器配置正确。Java Mail API中没有集成用于处理配置服务器以转发消息或添加/删除电子邮件账户等功能。

POP3邮局协议

POP3是Post Office Protocol 3的简称,即邮局协议第3版,该协议是在RFC 1939中定义的。它是Internet电子邮件的第一个离线协议标准,也就是说,POP3是一个简单而实用的邮件信息传输协议。目前在Internet上,大多数人都采用POP3来接收邮件。POP3为每个用户的每个邮箱提供支持,但是POP3并不支持查看邮件信息及统计新邮件的功能,因此,在使用Java Mail API时,如果想获取这些信息,需要自己进行计算。

IMAP 接收邮件协议

IMA P的含义是Internet消息访问协议,当前版本是第4版,也称作IMAP4,该协议是在RFC 2060中定义的。IMAP是接收消息的更加高级协议。使用IMAP时,所用邮件服务器必须支持该协议,但是如果所有邮件服务器只支持该协议,并不能使用全部IMAP协议,为了能够支持全部IMAP协议,所用邮件服务器还应该支持POP协议。在Java Mail程序通过IMAP协议可以在服务器上拥有包括多个文件夹的用户,并且这些文件夹可以被多个用户共享。
虽然IMAP协议具有更高级的功能,但是也不要让每个用户都使用,这是因为IMAP需要服务器接收新消息,发送消息给请求的用户,并在多个文件夹中为每个用户维护消息、备份信息,这会加重邮件服务器的负荷。

MIME

MIME是多用途的网际邮件扩充协议的简称。它不是一种邮件传输协议,而是用于定义传输内容(如消息的格式、附件等)的协议。许多文档都对MIME协议作了描述(包括RFC 2045、RFC 2046和RFC 2047)。MIME是对RFC 822的扩充,RFC 822规定了内容只包括采用ASCII编码的纯文本的邮件格式,而MIME允许在邮件中包含附件。作为Java Mail API的用户,一般不需要担心这些格式。

建立java mail 开发环境

获取Java Mail API
Java Mail API是发送Email的核心API,它可以到甲骨文的官方网站(http:/www.oracle.com)中下载,目前最新版本的文件名为javamail-1.4.7.zip。下载后解压缩到硬盘上,并在系统的环境变量CLASSPATH中指定mail.jar文件的放置路径,例如,将mail.jar文件复制到“C:\JavaMail”文件夹中,可以在环境变量CLASSPATH中添加以下代码:
C:\JavaMail\mail.jar;
如果不想更改环境变量,也可以把mail.jar放到实例程序的WEB-INF/lib目录下。

获取java mail api的激活框架

目前java mail api 的所有版本都需要JAF (javaBeans Activattion Framework)的支持,JAF为输入的任意数据块提供了支持,
并能相应地对其进行处理.

JAF 可以到网站(http://java.sun.com/javase/technologies/desktop/javabeans/jaf/downloads/index.html)

当前最新版本的JAF文件名为jaf-1_1_1.zip,下载后解压缩到硬盘上,并在系统的环境变量classpath 中指定activation.jar 文件的放置路径,例如:
将activation.jar 文件复制到”C:\JavaMail” 文件夹中,可以在环境变量classpath中添加以下代码:
C:\JavaMail\activation.jar

如果用eclipse 或者其他IDE 可以将activation 放到实例程序的WEB-INF/lib目录下.

在JDK 6 以上的开发包中已经封装了JavaMial API ,所以在JDK 6 的环境中不需要单独配置activation.jar

安装和配置邮件服务器

在互联网上发送和接收电子邮件前,必须配置SMTP服务器和POP3服务器,下面以Windows 2016 操作系统为列,介绍安装和配置SMTP 服务器和POP3服务器的具体步骤

可以使用第三方邮件服务器 Magic Winmail

  1. 打开服务器管理器
  2. 添加角色 和功能,添加web 服务 smtp服务 asp.net 等服务后安装.
  3. 网络上有详细教程

发送邮件的API

Session 类

Java Mail API 中提供了Session 类,用于定义保存诸如SMTP主机和认证信息的基本邮件会话.通过Session会话可以阻止恶意代码窃取其他用户在会话中的信息(包括用户名和密码等认证信息) 从而让其他工作顺利执行.

每个基于java mail的程序都需要创建一个Session或多个Session对象,由于Session对象 利用java.util.Properties对象,获取诸如邮件服务器,用户名,密码等信息,以及其他可在整个应用程序中共享的信息,所以在创建session对象前,需要先创建java.util.properties对象,创建java.util.properties对象的代码如下:

       Properties props=new Properties();

由于session 类的构造方法是私有的,所以必须调用getInstance()方法或getDefaultInstance()方法获得Session类的实例对象,

  1. 调用getInstance()方法获得Session类的实例对象,该方法每次调用时,都返回一个新的Session对象,getDefaultInstance()方法有以下两种语法格式.
       Session session=Session.getInstance(Properties props);//语法1
           Session session=Session.getInstance(Properties props,Authenticator authenticator); //语法2

props: 为java.util.Properties类对象,该对象中保存了实例化Session对象 索需的应用程序环境信息,以及客户端与邮件服务器建立连接所必需的会话信息.
authenticator : 为Authenticator对象,用于指定认证方式,如果在创建Session对象时,指定了该参数,那么使用这个Session对象的javamail客户端程序要向邮件服务器提交认证信息时.,将调用该Session对象中注册的Authenticator对象,从中获得用户认证信息后传递给邮件服务器.

如果在进行邮件发送时,不需要指定认证方式,可以通过以下代码创建一个Session类的实例对象的具体代码如下:

     Properties pro=new Properties();
         props.put("mail.smtp.host",mailserver)   //指定SMTP服务器
         props.put("mail.smtp.auth","true");    //指定客户端是否向邮件服务器提交认证
         Session sess=Session.getInstance(pro);     //创建一个Session对象
  1. 调用getDefaultInstance() 方法获得Session类的实例对象,该方法返回一个Session对象后,将把这个Session对象,设置为默认的Session对象,以后每次调用时,都将返回这个默认的Session对象,getDefaultInstance()方法有以下两种语法格式:
       `Session session=Session.getDefaultInstance(Properties props); //语法一`
          Session session=Session.getDefaultInstance(Properties props ,
           Authenticator authenticator);   //语法二

props:为java.util.Properties类的对象,用于指定认证方式,如果在创建Session对象时,指定该参数,那么使用这个Session对象的javamail客户端程序要向邮件服务器提交认证信息时,将调用该Session对象中注册的Authenticator对象,从中获得用户认证信息后传递给邮件服务器.
如果在进行邮件发送时,不需要指定认证方式,可以通过以下代码创建一个默认的Session类的实例对象的具体代码如下:

      Properties props=new Properties();
           props.put("mail.smtp.host",mailserver);   //指定SMTP 服务器
           props.put("mail.smtp.auth","true");   //指定客户端是否向邮件服务器提交认证
           Session sess=Session.getDefaultInstance(props); //创建一个Session对象 

Message 类中与发送邮件相关的方法

Message类是电子邮件系统的核心类,用于存储实际发送的电子邮件信息,Message类是一个抽象类,要使用该抽象类可以使用其子类MimeMessage,该类保存在javax.mail.internet包中,可以存储MIME类型和报头消息(在不同的RFC文档中均有定义),并且将消息的报头限制成智能使用US-ASSCII字符,尽管非ASCII字符可以被编码到某些报头字段中,
如果想对MimeMessage类进行操作,首先要实例化该类的一个对象,在实例化该类的对象时,需要指定一个Session对象,这可以通过将Session对象传递给MimeMessage的构造方法来实现,例如,实例化MimeMessage类的对象message的代码如下:

    `MimeMessage message=new MimeMessage(mailSession);`

实例化MimeMessage 类的对象message后,就可以通过该类的相关方法设置电子邮件信息的详细信息,下面将对MimeMessage类中常用的方法进行详细介绍.

  1. setText()方法 setText()方法用于指定纯文本信息的邮件内容,该方法只有一个参数,用于指定邮件内容.setText()方法的语法与格式如下:

      setText(String content)
      content:纯文本的邮件内容.
    
  2. setContent()方法
    setContent()方法用于设置电子邮件内容的基本机制,多数应用在发送HTML 等纯文本意外的信息,该方法包括两个参数,分别用于指定邮件内容和MIME类型,setContent()方法的语法格式如下:

       setContent(Object content,String type)   
       content: 用于指定邮件内容
       type: 用于指定邮件内容.
    

例如,指定邮件内容为”简单快乐”,类型为普通的文本,代码如下:
message.setContent(“简单快乐”,”text/plain”);

     setSubject(String subject)
     subject : 用于指定邮件的主题.
     例如,指定邮件主题为"来自北方的问候" 的代码如下:
     message.setSubject("来自北方的问候");
     saveChanges()方法

saveChange() 方法能够保证报头域同会话内容保持一致,savaChanges() 方法的使用方式如下:

     message.saveChanges();

setFrom() 方法
setFrom() 方法用于设置发件人地址,该方法只有一个参数,用于指定发件人地址.setFrom()方法的语法格式如下:

       setFrom(Address address)
       address:发件人地址,该地址通过InternetAddress类的对象指定.

例如,设置发件人地址为”wuyang136416@qq.com”的代码如下:

    InternetAddress from_)mail=new InternetAddress("wuyang136416@qq.com");
    message.setFrom(from_mail);

setRecipient()方法
setReciption()方法用于设置一个收件人地址,该方法有两个参数,分别用于指定收件人类型和收件人地址.
setRecipient()方法的语法格式如下:

 `setRecipient(RecipientType type,InternetAddress address);`

type: 收件人类型.可以使用以下3个常量来区分收件人的类型.

      (1) Message.RecipientType.TO//发送
      (2) Messgae.RecipientType.CC//抄送
      (3) Message.RecipientType.BCC //暗送

address : 用于指定收件人地址,该地址通过InternetAddress类的对象指定.
例如,设置收件人的类型为发送,地址为”wuyang136416@qq.com”的代码如下:

InternetAddress to_mail=new InternetAddress("wuyang136416@qq.com");
message.setRecipient(Message.Recipient.TO,to_mail);
特别说明:
Message类中还提供一个addRecipient()方法,用于增加一个收件人地址,该方法的参数意义与setRecipient()方法完全相同,这里不进行详细介绍。
l  setRecipients()方法
setRecipients()方法用于设置一组收件人地址。该方法有两个参数,分别用于指定收件人类型和多个收件人地址。setRecipients()方法的语法格式如下:
setRecipients(RecipientType type, InternetAddress[] addresses);
type:收件人类型。可以使用以下3个常量来区分收件人的类型。
(1)Message.RecipientType.TO//发送
(2)Message.RecipientType.CC//抄送
(3)Message.RecipientType.BCC //暗送
addresses:是一个保存InternetAddress对象的数组,可以通过该数组指定多个收件人地址。
例如,设置收件人的类型为发送,地址为to1、to2和to3所指定的邮箱地址的代码如下:
InternetAddress[] to_mail={new InternetAddress(to1),new InternetAddress(to2),new InternetAddress(to3)};
message.addRecipients(Message.RecipientType.TO ,to_mail);
在上面的代码中,to1、to2和to3分别表示收件人邮箱地址的字符串。
说明

setRecipient()方法通常应用在发送单封邮件时,而setRecipients()方法则应用在邮件群发时。

说明

Message类中还提供一个addRecipients() 方法,用于增加一组收件人地址,该方法的参数意义与setRecipients()方法完全相同,这里不进行详细介绍。
l setSentDate ()方法
setSentDate()方法用于设置发送邮件的时间。该方法只有一个参数,用于指定发送邮件的时间。setSentDate ()方法的语法格式如下:
setSentDate(Date date);
date:用于指定发送邮件的时间。
例如,指定发送邮件的时间为当前系统时间的代码如下:
message.setSentDate(new Date());

Address 类

Address 类用于设置电子邮件的响应地址,Address类是一个抽象类,要使用该抽象类可以使用其子类internetAddress. 该类保存在javax.mail.internet包中,可以按照指定的内容设置电子邮件地址

如果想对InternetAddress 类进行操作,首先要实例化该类的一个对象,在实例化该类的够着方法,代码如下:
(1)创建带有电子邮件地址并显示其他标识信息的地址,可以将电子邮件地址和附加信息同时传递给InternetAddress 类的构造方法,代码如下:
InternetAddress address =new InternetAddress(wuyang136416@qq.com);
(2)创建带有电子邮件地址并显示其他标识信息的地址,可以将电子邮件地址和附加信息同时传递给InternetAddress类的构造方法,代码如下:
InternetAddress address = new InternetAddress(“wuyang136416@qq.com”,”Wu Yang”);

说明

Java Mail API 没有提供检查电子邮件地址有效性的机制,如果需要读者可以自己编写检查电子邮件地址是否有效的方法.

Authenticator类

Authenticator类用于代表一个可以对外提供用户认证信息的对象,它提供的用户认证信息封装在一个PasswordAuthentication类型的对象中。Authenticator类是一个抽象类,要使用该抽象类首先需要创建一个Authenticator的子类,并重构getPasswordAuthentication()方法,具体代码如下:
package com.wgh;

   import javax.mail.Authenticator;

    import javax.mail.PasswordAuthentication;

    public class WghAuthenticator extends Authenticator {
   

    public PasswordAuthentication getPasswordAuthentication() {

        String username = "wgh717";                                                       //邮箱登录帐号

        String pwd = "111111";                                                         //登录密码

        return new PasswordAuthentication(username, pwd);

          }

    }

然后再通过以下代码实例化新创建的Authenticator的子类,并将其与Session对象绑定。

     Authenticator auth = new WghAuthenticator ();

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

Transport类

Transport类用于使用指定的协议(通常是SMTP)发送电子邮件。Transport类提供了以下两种发送电子邮件的方法。

(1)只调用其静态方法send(),按照默认协议发送电子邮件,代码如下:
Transport.send(Message message);
message:代表邮件内容的Message对象.
在调用send()方法发送邮件时,首先从参数Message对象中获取Session对象,然后调用Session.getTransport()方法获得用于发送邮件的Transport实例对象,在调用Transport 对象的connect()方法链接邮件服务器,最后调用transport对象的sendMessage()方法发送邮件,并调用close()方法断开与服务器的链接.
(2) 首先从指定协议的会话中获取一个特定的实例,然后传递用户名和密码,在发送信息,最后关闭链接,代码如下:

       Transport transport =sess.egtTransport("smtp");
       Transport.connect(servername,from,password);
       Transport.sendMessage(message,message.getAllRecipients);
       transport.close();

在发送多个消息时,建议采用第二种方法,因为它将保持消息间活动服务器的连接,而是用第一种方法时,系统将为每一个方法的调用建立一条独立的连接.

注意
如果想要查看经过邮件服务器发送邮件的具体命令,可以用session.setDebug(true)方法设置调试标志。

l  connect()方法

Transport类提供的connect()方法,用于建立与邮件服务器之间的连接。connect()方法的语法格式如下:

public void connect()

public void connect(String host,String user,String password)

public void connect(String host,int port,String user,String password)

host:用于指定主机名。

user:用于指定用户名。

password:用于指定密码。

port:用于指定SMTP采用的端口号,默认值为25。

例如,通过指定主机名、用户名和密码连接SMTP服务器的代码如下:

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

transport.connect(mailserver,from,password);

l  close()方法

Transport类提供的close()方法,用于断开与邮件服务器之间的连接。close()方法的语法格式如下:

public void close()

l  sendMessage()方法

Transport类提供的sendMessage ()方法,用于向指定邮件地址发送邮件。sendMessage()方法的语法格式如下:

public abstract void sendMessage(Message msg,Address[] addresses)

msg:代表邮件内容的Message对象。

addresses:代表收件人地址的Address数组,这个数组中可以指定一个或多个收件人地址。

例如,向邮件消息内部定义的全部收件人发送邮件的代码如下:

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

接收邮件的API

Store类

Store类定义了用于保存文件夹间层级关系的数据库,以及包含在文件夹之中的信息,该类也可以定义存取协议的类型,以便存取文件夹与信息
在获取会话后,就可以使用用户名和密码或Authenticator 类来连接Store类,与Transport 类一样,,,连接Store类时,也需要先告诉Store 类将使用什么协议.

    使用POP3 协议链接Store类,代码如下:
   Stroe store =session.getStore("pop3");
   store.connect(host,username,password);

使用IMAP协议链接Store类,代码如下:
Store store=session.getStore(“imap”);
store.connect(host,username,password);

说明
如果使用POP3协议,只可以使用INBOX文件夹,但是使用IMAP协议,则可以使用其他的文件夹。

Store类还提供了isConnected()方法,用于检测客户端与邮件是否已连接。isConnected()方法的语法格式如下:

public boolean isConnected()

该方法的返回值为true时,表示已经连接,否则表示未连接。

在使用Store类读取完邮件信息后,需要及时关闭连接。关闭Store类的连接可以使用以下代码:

store.close();

Folder类

Folder类
Folder类代表邮件夹,它提供了一系列访问邮件夹的方法。例如,获取(fetch)、备份(copy)、附加(append)以及删除(delete)等方法,通过这此方法可以检索出邮件夹中的邮件对象。

在连接Store类后,就可以打开并获取Folder类中的消息。打开并获取Folder类中的信息的代码如下:

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

folder.open(Folder.READ_ONLY);//打开邮件夹

Message message[] = folder.getMessages();  //获取邮件夹中的邮件

在采用IMAP协议时,读取未读邮件和已读邮件比较简单,只需要根据其邮件的读标记进行读取,但是由于POP3协议不支持标记读取状态的标记,所以在处理邮件的读状态时,需要借助邮件的UID(邮件的UID是邮件服务器在处理每封邮件时为其分配的一个独一无二的编号,这个编号是一个正的长整数,一般这是一个递增的值。利用这个UID可以实现邮件的读状态的处理)。需要大家注意的是,在获取邮件的UID时,不能使用Folder类打开邮件夹,而需要使用POP3Folder类。获取邮件夹中每封邮件的UID的具体代码如下:

final POP3Folder folder = (POP3Folder) store.getFolder("inbox");

folder.open(Folder.READ_WRITE); //打开邮件夹

FetchProfile profile = new FetchProfile();

profile.add(UIDFolder.FetchProfileItem.UID);

profile.add(FetchProfile.Item.ENVELOPE);

Message[] messages = folder.getMessages();

folder.fetch(messages, profile);

for (int i = 0; i < messages.length; i++){

  System.out.println(folder.getUID(messages[i])); 

}

另外,Folder类或POP3Folder类还提供了search()方法,通过该方法可以搜索符合指定条件的邮件,该方法有以下两种语法格式:

Message[] message=folder.search(searchTerm);   //搜索整个邮件夹

Message[] message=folder.search(searchTerm,messageArr);//在指定的邮件数组中搜索邮件

searchTerm:为SearchTerm类的对象。

messageArr:为Message数组。

在使用Folder类或POP3Folder类读取完邮件信息后,需要及时关闭对文件夹的连接。关闭Folder类或POP3Folder类连接的语法格式如下:

folder.close(Boolean boolean);

boolean:用于指定是否通过清除已删除的消息来更新文件夹。

例如,在关闭邮件夹时,不删除已经设置删除标记的邮件,可以使用以下代码:

folder.close(false);//关闭邮件夹

Flags类

Flags类是一组邮件标记的集合,邮件标记用于标识邮件的使用状态。例如,邮件的已读标记和删除标记等。Java Mail组件中的邮件标记分为系统标记和用户标记,其中,系统标记是指Flags.Flag类中指定的标记,而用户标记是指用户自定义的标记。

Flag类是Flags的内部类,在该类中预定义了一些用来表示各种邮件标记的常量,如表1所示。

表1   Java Mail提供的系统邮件标记

常量
 -- 说明

Flags.Flag.ANSWERED
-- 邮件回复标记,用于指定邮件是否已回复

Flags.Flag.DELETED
-- 邮件删除标记,用于指定邮件是否需要删除

Flags.Flag.DRAFT
-- 草稿邮件标记,用于指定邮件是否为草稿

Flags.Flag.FLAGGED
-- 用于标记邮件是否为回收站中的邮件

Flags.Flag.RECENT
-- 新邮件标记,用于指定邮件是否为新邮件

Flags.Flag.SEEN
-- 邮件阅读标记,用于指定邮件是否已被阅读

Flags.Flag.USER
-- 用于检索底层系统是否支持用户自定义标记,该标记只读
特别注意
POP3协议只支持Java Mail中的Flags.Flag.DELETED标记,而IMAP协议则支持表1所示的全部邮件标记。

Message类中与接收邮件相关的方法

通过folder类的getMessage()或getMessages()方法获取邮件夹中的邮件对象后,就可以通过Message类中提供的一系列getXXXX()方法获得邮件的详细信息.
getForm()方法

getForm()方法用于返回发件人地址,该方法的语法格式如下:

public abstract Address[] getForm()

l  getSendDate()方法

getSendDate ()方法用于返回邮件的发送日期,该方法的语法格式如下:

public abstract java.util.Date getSendDate()

getRecipients()方法

getRecipients()方法用于返回指定类型的收件人地址,该方法的语法格式如下:

public abstract Address[] getRecipients(Message.RecipientType type)

 type:用于指定收件人的类型,该参数的值同21.3.2节介绍的setRecipient()方法的type参数值相同。

getAllRecipients()方法

getAllRecipients()方法用于返回所有的收件人地址,该方法的语法格式如下:

public Address[] getAllRecipients()

getSubject()方法

getSubject()方法用于返回邮件的主题,该方法的语法格式如下:

public abstract String getSubject()

getContent()方法

getContent()方法用于返回邮件体的内容,该方法的语法格式如下:

Object getSubject()

getContent()方法把邮件体内容作为一个Java对象返回,对象的类型根据邮件体的内容确定。

案列集锦

实现邮箱登陆案列

本程序的实现比较简单, 只是简单的实现登陆邮箱的功能,运行效果图如图1所示,首先输入邮箱服务器的IP地址,如果是本机,也可以输入localhost,然后输入注册的邮箱地址和密码,单击”登陆”按钮后,将弹出登录成功的提示信息.

实现过程如下:

  1. 创建index.jsp页面,该页面为邮箱登陆的表单页,并且设置表单提交到一个Servlet,具体代码如下:
 <%@page contentType="text/html" pageEncoding="GBK"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    <title>邮箱登录</title>
    <link 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值