[转载]JavaMail 深入浅出

本文深入介绍了JavaMail API的基础知识和具体应用,包括SMTP、POP、IMAP等邮件传输协议的概念,以及如何使用JavaMail API进行邮件发送和接收的实际操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我干软件开发也有一点的年头了,回头想想,也经历了不少的酸甜苦辣,为解决了复杂的问题快乐过.也为不分昼夜的加班赶工程郁闷过.不过这些都没能减少我对计算机的热情,我对程序的喜好.以前对JavaMail也有一些学习性的认识,不过一直没在实际的项目中应用过.直到最近的一个项目,需要JavaMail所以我打算认真的学习一下这种技术,因为我目前擅长的是Struts,而Struts又不具备邮件发送的功能,所以我要深刻的学习一下JavaMailAPI.所以在我学会了JavaMail的基本操作的同时也将这篇文章献给大家,虽然技术含量不高,但是希望能对一些刚刚接触JavaMail的同道中人有所帮助.好了闲话少说进入正题,首先介绍几个邮件传输协议,虽然说不了解这些协议也可以实用JavaMailAPI, 但是我始终认为,如果不透彻的了解一种技术的本质,即使会用了也是照葫芦画瓢,换一种模式也许就玩不转了.
SMTP: 简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)由RFC821定义,它定义了发送邮件的机制,在JavaMail环境中,基于JavaMail的程序将和因特网服务供应商 ISP(internet Service Provider ’ s)SMTP服务器通信.SMTP服务器会中转消息给接收方SMTP服务器以便最终让用户经由POP或者IMAP获得.

POP: 代表邮局协议(Post Office Protocol).目前的版本是3.所以一般都称之为POP3.这个协议是由RFC1939定义的.POP是一种机制,因特网上多大数用户用它得到邮件.它规定每个用户一个邮箱的支持.使用POP协议的时候,用户的许多性能并不是由POP协议支持的,如查看几封新邮件消息这个功能,这些功能内建在如 Eudora或MicrosoftOutlook之类的程序中,它们记住一些事.所以在用JavaMail的时候,如果你想要这些信息,你就必须自己算了.

IMAP: 是更高级的用户接收消息的协议,被定义在RFC2060中,IMAP代表因特网消息访问协议(Internet Message Access Protocol),目前用的版本是4,所以也叫做IMAP4.在用到IMAP的时候,邮件服务器必须支持这个协议,不能仅仅把使用POP的程序用于 IMAP,并指望它支持IMAP所有性能.

MIME:是因特网邮件扩展标准(Multipurpose Internet Mail Extensions).它不是邮件传输协议,但是对于传输的内容的消息,附件以及其他的内容定义了格式.可以理解成一个定义合适的标准.

NNTP:因为JavaMail将供应商和所有其它的东西分开了,您就能轻松添加额外的协议支持.NNTP 就是网络新闻传输协议.

JavaMailAPI可以到 http://java.sun.com/products/javamail/index.html 进行下载,并将mail.jar添加到classpath即可.

JAF框架可以到 http://java.sun.com/products/javabeans/glasgow/jaf.html 进行下载,并将activation.jar添加到classpath即可.

如果实用J2EE就没由什么特定非要用基本的JavaMailAPI了.J2EE的类就能处理了.只要确保j2ee.jar文件在classpath中就Ok了.

下面我用一个最简单的例子还演示第一条消息的发送.

1,获取系统Properties.

Properties props = System.getProperties();

2,将您的SMTP服务器名添加到mail.smtp.host关键字的属性中.

Props.pout( “ mail.smtp.host ” ,host);

3,获取基于Properties Session对象.

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

4,从Session创建一个MimeMessage.

MimeMessage message = new MimeMessage(session);

5,设置消息from域.

Message.setForm(new InternetAddress(from));

6,设置to域.

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

7,设置消息主题.

message.setSubject( “ HelloJavaMail ” );

8,设置消息内容.

Message.setText( “ Welcome to JavaMail ” );

9发送消息.

Transport.send(message);

10,在编译用运的时候传递MSTP服务器,from地址,to地址.

通过简单的接触了JavaMail相信大家多邮件发送也有了简单的了解和认识,下面我主要研究一下它的具体功能,也就是说具体的接口或类的含义.

Session 类定义了一个基本的邮件会话,所有的其他类都是由这个session才得意生效的,Session对象用java.util.Properties对象获取信息,如邮件服务器,用户名,密码及整个应用程序中共享的其他信息.类的构造器是此有的,private.它能用getDefaultInstance ()方法来共享.获取Session对象的方方法如下:

Properties props = new Properties();

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

Null参数都是Authenticator对象,在这里没有使用.

对于大多数情况,共享的session已经足够用了.

Message 消息类,在获得了Session对象后,就可以继续创建要发送的消息.因为Message是个抽象类,您必须用一个子类,多数情况下为 java.mail.internet.MimeMessage.这个能理解成MIME类型和头的电子邮件消息.正如不同的RFC中定义的,虽然在某些头部域非ASCII字符也能被编译,但是Message头只能被限制用US-ASCII字符.要创建一个Message请将Session对象传递给 MimeMessage的构造器.

MimeMessage message = newMimeMessage(session);

一旦获得消息,就可以设置各个部分了.最基本的就是setContent()方法,例如/

message.setContent( “ Hello ” , ” text/plain ” );

如果知道在实用MimeMessage,而且消息是纯文本格式,就可以用setText()方法,它只需要代表实际内容的参数.(Mime类型缺省为text/plain)

用setSubject()方法设置subject(主题);

message.setSubject( “ 主题 ” );

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

InternetAddress类.若创建的地址只包含电子邮件地址,只要传递电子邮件地址给构造器就可以了.例如:Address address = new InternetAddress( “ it5719@163.com ” );

若希望名字挨着电子邮件现实,就可以把它传递给构造器,如下:

Address address = new InternetAddress( “ it5719@163.com ” , ” 我心依旧 ” );

需要为消息的from 域和to域创建地址对象,除非邮件服务器阻止,没有什么能阻止你发送一段看上去是任何人的消息了呵呵.一旦创建address将他们域消息连接方法有两种,如要要识别发件人的就可以用setFrom()和setReplyTo方法.然后message.setFrom(address);

需要实用多个from地址的就用addFrom()方法.例子如下:

Address[] address = ,.,. ; message.addFrom(address);

若要识别消息recipient收件人,就要实用addRecipient()方法了.例如:

message.addRecipient(type,address)

Authenticator 与java.net类一样,JavaMailAPI也可以利用Authentcator通过用户名密码访问受保护的资源.对于JavaMail来说,这些资源就是邮件服务器,Authentcator类在javax.mail包中.要使用Authenticator,首先创建一个抽象的子类,并从

GetPasswordAuthentication 方法中返回passwordAuthentication实例,创建完成后,您必须向session注册Authenticator,然后在需要认证的时候会通知它,其实说白了就是把配置的用户名和密码返回给调用它的程序.例如:

Properties props = new properties();

Authenticator auth = new MailAuthenticator()//接口声明,创建自己新类的实例.

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

Transport消息发送传输类,这个类用协议指定的语言发送消息,通常是SMTP,它是抽象类,它的工作方式与Session有些类似,尽调用静态方法send()方法,就OK了.例如:

Transport.send(message);

或者也可以从针对协议的会话中获取一个特定的实例,传递用户名和密码.发送消息,然后关闭连接,例如:

message.saveChanges();

transport transport = session.getTreansport( “ smtp ” );//指定的协议

transport.connect(host,username,password);

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

transport.close();

如果要观察传到邮件服务器上的邮件命令,请用session.setDubug(true)设置调试标志.

Store和folder用session获取消息,与发送消息开始很相似,但是在session得到后,很可能实用用户名和密码或实用Authenticator连接到一个Store.类似于Transport,也是一样要告诉store用什么协议.例如

Store store = session.getStore( “ pop3 ” );

Store.connect(host,username,password);

连接到Store之后,接下来,获得一个folder,必须打开它就可以读取里边的消息了.

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

folder.open(Folder.READ_ONLY);

Message[] message = folder.getMessages();

POP3唯一可用的文件夹就是INBOX,如果实用IMAP,还可以用其他的文件夹.

当读到了具体的message以后,就可以用getContent来获取内容,或者用writeTo()将内容写入流,getContent()方法只能得到消息内容,而writeTo()的输出却包含消息头.

System.out.println(((MimeMessage)message).getConntent());

一旦读取完毕邮件,要关闭store和folder的连接.

folder.colse(boolean);

store.colse();

传递给folder的close()方法的boolean参数表示是否清楚已删除的消息从而更新folder.

上面就是JavaMail邮件操作的基本的常用类,我觉得理解了这几个类的机制,基本就可以处理一般的邮件操作了.下面是一个我写的JavaMail实现邮件发送的代码.

首先是一个Authenticator类的实现:记录用户名和密码:

import javax.mail.*;





public class MailAuthenticator extends Authenticator

{

//******************************

//由于发送邮件的地方比较多,

//下面统一定义用户名,口令.

//******************************

public static String HUAWEI_MAIL_USER = "it5719@163.com";

public static String HUAWEI_MAIL_PASSWORD = "密码";





public MailAuthenticator()

{

}



protected PasswordAuthentication getPasswordAuthentication()

{

return new PasswordAuthentication(HUAWEI_MAIL_USER, HUAWEI_MAIL_PASSWORD);

}



}



这个类是发送邮件的类.





package com.deepdo.common.mail;



/**

* 此处插入类型说明。

* 创建日期:(2006-4-21 14:57:16)

* @author:张宏亮

*/



import java.util.*;

import java.io.*;

import javax.mail.*;

import javax.mail.internet.*;

import javax.activation.*;





public class SendMail {



//要发送Mail地址

private String mailTo = null;

//Mail发送的起始地址

private String mailFrom = null;

//SMTP主机地址

private String smtpHost = null;

//是否采用调试方式

private boolean debug = false;



private String messageBasePath = null;

//Mail主题

private String subject;

//Mail内容

private String msgContent;



private Vector attachedFileList;

private String mailAccount = null;

private String mailPass = null;

private String messageContentMimeType ="text/html; charset=gb2312";



private String mailbccTo = null;

private String mailccTo = null;

/**

* SendMailService 构造子注解。

*/

public SendMail() {

super();



}



private void fillMail(Session session,MimeMessage msg) throws IOException, MessagingException{



String fileName = null;

Multipart mPart = new MimeMultipart();

if (mailFrom != null) {

msg.setFrom(new InternetAddress(mailFrom));

System.out.println("发送人Mail地址:"+mailFrom);

} else {

System.out.println("没有指定发送人邮件地址!");

return;

}

if (mailTo != null) {

InternetAddress[] address = InternetAddress.parse(mailTo);

msg.setRecipients(Message.RecipientType.TO, address);

System.out.println("收件人Mail地址:"+mailTo);

} else {

System.out.println("没有指定收件人邮件地址!");

return;

}



if (mailccTo != null) {

InternetAddress[] ccaddress = InternetAddress.parse(mailccTo);

System.out.println("CCMail地址:"+mailccTo);

msg.setRecipients(Message.RecipientType.CC, ccaddress);

}

if (mailbccTo != null) {

InternetAddress[] bccaddress = InternetAddress.parse(mailbccTo);

System.out.println("BCCMail地址:"+mailbccTo);

msg.setRecipients(Message.RecipientType.BCC, bccaddress);

}

msg.setSubject(subject);

InternetAddress[] replyAddress = { new InternetAddress(mailFrom)};

msg.setReplyTo(replyAddress);

// create and fill the first message part

MimeBodyPart mBodyContent = new MimeBodyPart();

if (msgContent != null)

mBodyContent.setContent(msgContent, messageContentMimeType);

else

mBodyContent.setContent("", messageContentMimeType);

mPart.addBodyPart(mBodyContent);

// attach the file to the message

if (attachedFileList != null) {

for (Enumeration fileList = attachedFileList.elements(); fileList.hasMoreElements();) {

fileName = (String) fileList.nextElement();

MimeBodyPart mBodyPart = new MimeBodyPart();



// attach the file to the message

FileDataSource fds = new FileDataSource(messageBasePath + fileName);

System.out.println("Mail发送的附件为:"+messageBasePath + fileName);

mBodyPart.setDataHandler(new DataHandler(fds));

mBodyPart.setFileName(fileName);

mPart.addBodyPart(mBodyPart);

}

}

msg.setContent(mPart);

msg.setSentDate(new Date());

}

/**

* 此处插入方法说明。

*/

public void init()

{



}

/**

* 发送e_mail,返回类型为int

* 当返回值为0时,说明邮件发送成功

* 当返回值为3时,说明邮件发送失败

*/

public int sendMail() throws IOException, MessagingException {



int loopCount;

Properties props = System.getProperties();

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

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



MailAuthenticator auth = new MailAuthenticator();



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

session.setDebug(debug);

MimeMessage msg = new MimeMessage(session);

Transport trans = null;

try {



fillMail(session,msg);

// send the message

trans = session.getTransport("smtp");

try {

trans.connect(smtpHost, MailAuthenticator.HUAWEI_MAIL_USER, MailAuthenticator.HUAWEI_MAIL_PASSWORD);//, HUAWEI_MAIL_PASSWORD);

} catch (AuthenticationFailedException e) {

e.printStackTrace();

System.out.println("连接邮件服务器错误:");

return 3;

} catch (MessagingException e) {

System.out.println("连接邮件服务器错误:");

return 3;

}



trans.send(msg);

trans.close();



} catch (MessagingException mex) {

System.out.println("发送邮件失败:");

mex.printStackTrace();

Exception ex = null;

if ((ex = mex.getNextException()) != null) {

System.out.println(ex.toString());

ex.printStackTrace();

}

return 3;

} finally {

try {

if (trans != null && trans.isConnected())

trans.close();

} catch (Exception e) {

System.out.println(e.toString());

}

}

System.out.println("发送邮件成功!");

return 0;

}

public void setAttachedFileList(java.util.Vector filelist)

{

attachedFileList = filelist;

}

public void setDebug(boolean debugFlag)

{

debug=debugFlag;

}

public void setMailAccount(String strAccount) {

mailAccount = strAccount;

}

public void setMailbccTo(String bccto) {

mailbccTo = bccto;

}

public void setMailccTo(String ccto) {

mailccTo = ccto;

}

public void setMailFrom(String from)

{

mailFrom=from;

}

public void setMailPass(String strMailPass) {

mailPass = strMailPass;

}

public void setMailTo(String to)

{

mailTo=to;

}

public void setMessageBasePath(String basePath)

{

messageBasePath=basePath;

}

public void setMessageContentMimeType(String mimeType)

{

messageContentMimeType = mimeType;

}

public void setMsgContent(String content)

{

msgContent=content;

}

public void setSMTPHost(String host)

{

smtpHost=host;

}

public void setSubject(String sub)

{

subject=sub;

}



public static void main(String[] argv) throws Exception

{

for(int i = 0;i<10;i++) {

SendMail sm = new SendMail();

sm.setSMTPHost("SMTP地址");

sm.setMailFrom("发送地址");

sm.setMailTo("目标地址");

sm.setMsgContent("内容");

sm.setSubject("标题");

sm.sendMail();

}

}

}
javaMail的详细文档,都有以下多有类的详细信息: ACL Address AddressException AddressStringTerm AddressTerm AndTerm AuthenticationFailedException Authenticator BodyPart BodyTerm ByteArrayDataSource ComparisonTerm ConnectionAdapter ConnectionEvent ConnectionListener ContentDisposition ContentType DateTerm DeliveryStatus DispositionNotification FetchProfile FetchProfile.Item Flags Flags.Flag FlagTerm Folder FolderAdapter FolderClosedException FolderEvent FolderListener FolderNotFoundException FromStringTerm FromTerm Header HeaderTerm HeaderTokenizer HeaderTokenizer.Token IllegalWriteException IMAPFolder IMAPFolder.FetchProfileItem IMAPFolder.ProtocolCommand IMAPMessage IMAPSSLStore IMAPStore IntegerComparisonTerm InternetAddress InternetHeaders InternetHeaders.InternetHeader MailDateFormat MailEvent MailHandler MailSSLSocketFactory Message Message.RecipientType MessageAware MessageChangedEvent MessageChangedListener MessageContext MessageCountAdapter MessageCountEvent MessageCountListener MessageHeaders MessageIDTerm MessageNumberTerm MessageRemovedException MessagingException MethodNotSupportedException MimeBodyPart MimeMessage MimeMessage.RecipientType MimeMultipart MimePart MimePartDataSource MimeUtility Multipart MultipartDataSource MultipartReport NewsAddress NoSuchProviderException NotTerm OrTerm ParameterList ParseException Part PasswordAuthentication POP3Folder POP3Message POP3SSLStore POP3Store PreencodedMimeBodyPart Provider Provider.Type Quota Quota.Resource QuotaAwareStore ReadOnlyFolderException ReceivedDateTerm RecipientStringTerm RecipientTerm Report Rights Rights.Right SearchException SearchTerm SendFailedException SentDateTerm Service Session SharedByteArrayInputStream SharedFileInputStream SharedInputStream SizeTerm SMTPAddressFailedException SMTPAddressSucceededException SMTPMessage SMTPSendFailedException SMTPSSLTransport SMTPTransport Store StoreClosedException StoreEvent StoreListener StringTerm SubjectTerm Transport TransportAdapter TransportEvent TransportListener UIDFolder UIDFolder.FetchProfileItem URLName
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值