JavaMail技术基础概念整理归纳
一、邮件传输协议(转载网络并整理)
1.SMTP:简单邮件传输协议(Simple Mail Transfer Protocol)
由RFC821定义,定义了发送邮件的机制
在JavaMail环境中,基于JavaMail的程序将和因特网服务供应商ISP(internet Service Provider's)SMTP服务器通信
SMTP服务器会中转消息给接收方SMTP服务器以便最终让用户经由POP或者IMAP获得
2.POP:代表邮局协议(Post Office Protocol)目前常用版本为3 也称pop3
此协议是由RFC1939定义
POP是一种机制,因特网上多大数用户用它得到邮件.
它规定每个用户一个邮箱的支持.
注意:
在使用POP协议的时候,用户的许多性能并不是由POP协议支持的
如:查看几封新邮件消息这个功能
这些功能内建在如Microsoft Outlook之类的程序中
所以在用JavaMail的时候,如果想要这些信息,你就必须自己实现了
3.IMAP:更高级的用户接收消息的协议,被定义在RFC2060中
IMAP代表因特网消息访问协议(Internet Message Access Protocol)
目前用的版本是4,所以也叫做IMAP4.
在用到IMAP的时候,邮件服务器必须支持这个协议,不能仅仅把使用POP的程序用于IMAP,并指望它支持IMAP所有性能
它与POP3的区别是:
IMAP用密文在网络间传输消息,比POP3的明文传输要安全
4.MIME:是因特网邮件扩展标准(Multipurpose Internet Mail Extensions)
注意:
它不是邮件传输协议,但是对于传输的内容的消息,附件以及其他的内容定义了格式.
可理解成一个定义合适的标准.
5.NNTP:因为JavaMail将供应商和所有其它的东西分开了,您就能轻松添加额外的协议支持.NNTP 就是网络新闻传输协议.
二、获得jar(转载网络)
JavaMailAPI可以到http://java.sun.com/products/javamail/index.html下载
将mail.jar添加到classpath即可 如:JavaMail 1.4.1
JAF框架可以到http://java.sun.com/products/javabeans/glasgow/jaf.html下载
如:jaf 1.0.2
将activation.jar添加到classpath即可
如果使用J2EE则可以不用基本的JavaMailAPI了,确保j2ee.jar在classpath中即可
三、常用API(转载网络并整理)
JavaMail核心类结构
javax.mail的包下面存在着一些核心类:
Session、Message、Address、 Authenticator、Transport、Store、Folder
javax.mail.internet包中还有一些常用的子类
1.javax.mail.Session类
定义了基本的邮件会话,进行收发邮件的工作都是基于这个会话
Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息
使用Session类提供的getDefaultInstance()这个静态工厂方法获得一个默认的Session对象
Properties props = new Properties();
Session.getDefaultInstance(props, null);
注意第2个参数为null,则表示不使用邮件授权
2.javax.mail.Message类
Message是个抽象类,大多数情况下,使用javax.mail.internet.MimeMessage子类
该类是使用MIME类型、MIME信息头的邮箱信息
MimeMessage msg = new MimeMessage(session);
建立MimeMessage对象后,我们需要设置它的各个part,对于MimeMessage类来说,这些part就是MimePart接口
对于一般发送文本信息的邮件:
msg.setContent("Hello", "text/plain"或"text/html;charset=gb2312");
或
msg.setText("Hello"); 针对内容是存文本
msg.setSubject(string) 对邮件设置邮件主题
3.javax.mail.Address 邮件地址类 抽象类
一般使用javax.mail.internet.InternetAddress子类
(1)传入代表邮件地址的字符串,建立一个邮件地址类:
Address address = new InternetAddress("xxxx@163.com");
或
Address address = new InternetAddress("xxx@163.com", "名字/姓名");
(2)建立邮件地址类后,通过MimeMessage对象的setFrom()和setReplyTo()两种方法设置邮件的发信人
msg.setFrom(address);
或
msg.setReplyTo(address);
addForm()方法增加发信人
(3)设置收信人
MimeMessage对象的addRecipient()方法增加收信人
msg.addRecipient(Message.RecipientTyp, address)
或
msg.setRecipients(Message.RecipientType,address数组); 同时发送给多个地址
Message对象.RecipientType的常量来区分收信人的类型:
Message.RecipientType.TO 主送
Message.RecipientType.CC 抄送
Message.RecipientType.BCC 隐蔽抄送
4.javax.mail.Authenticator类 抽象类
JavaMail API通过使用授权类以用户名、密码的方式访问那些受保护资源(指服务器)
采用继承此类的方式,并且该继承类必须具有返回javax.mail.PasswordAuthentication对象(存储认证时用到的用户名,密码)
并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类
参考如下代码:
//SMTP验证类(内部类),继承javax.mail.Authenticator
class MyAuthenticator extends Authenticator {
private String strUser;
private String strPwd;
public MyAuthenticator(String user, String password) {
this.strUser = user;
this.strPwd = password;
}
//方法返回javax.mail.PasswordAuthentication对象
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(strUser, strPwd);
}
}
在构造会话对象时:
Properties props = System.getProperties();
props.put("mail.smtp.auth","true");//设置执行SMTP授权验证
MyAuthenticator auth=new MyAuthenticator(MailUserName,MailPassword);
//得到默认的对话对象
Session session=Session.getDefaultInstance(props,auth);
5.javax.mail.Transport类 抽象类
发送邮件时用到
这个类实现了发送信息的协议(SMTP)
第一种发送方式:
使用这个类的静态方法send()来发送邮件
Transport.send(MimeMessage对象);
另一种发送方式:
由Session获得相应协议对应的Transport实例
通过传递用户名、密码、邮件服务器主机名等参数建立与邮件服务器的连接
使用sendMessage()方法发送,最后关闭连接
参考如下代码:
MimeMessage对象.saveChanges();
Transport transport = session.getTransport("smtp");
transport.connect(smtphost, username, password);
transport.sendMessage(MimeMessage对象, MimeMessage对象.getAllRecipients());
transport.close();
注意:发送方式二是个很好的方法,尤其是在同一个邮件服务器上发送多个邮件时
因为这时我们将在连接邮件服务器后连续发送邮件,然后再关闭掉连接
send()这个基本的方法是在每次调用时进行与邮件服务器的连接的
对于在同一个邮件服务器上发送多个邮件来讲其效率比较低
注意:如果需要在发送邮件过程中监控mail命令的话,在发送前设置debug标志:
session.setDebug(true)
6.javax.mail.Store和javax.mail.Folder类
接收邮件,在获得Session后,从Session中获取特定类型的Store,然后连接到Store(Store代表了存储邮件的邮件服务器)
在连接Store的过程中,极有可能需要用到用户名、密码或者Authenticator。
Store store = session.getStore("pop3");
或
Store store = session.getStore("imap");
store.connect(host, username, password);
连接到Store后,一个Folder对象(目录对象)通过Store的getFolder()方法返回,可从这个Folder中读取邮件信息
//从Store中获得INBOX这个Folder(对于POP3协议只有一个名为INBOX的Folder有效)
Folder folder = store.getFolder("INBOX");
以只读 (Folder.READ_ONLY)的方式打开Folder
folder.open(Folder.READ_ONLY);
//调用Folder的getMessages()方法得到目录中所有Message的数组
Message message[] = folder.getMessages();
注意:
对于POP3协议只有一个名为INBOX的Folder有效,而对于IMAP协议,我们可以访问多个Folder
SUN在设计Folder的getMessages()方法时采取了很智能的方式:
先接收新邮件列表,然后再需要的时候(比如读取邮件内容)才从邮件服务器读取邮件内容
在读取邮件时,可以用Message类的getContent()方法接收邮件或是writeTo()方法将邮件保存
getContent()方法只接收邮件内容(不包含邮件头)
writeTo()方法将包括邮件头
System.out.println(((MimeMessage)message).getContent());
读取邮件内容后,要关闭Folder和Store
folder.close(aBoolean); //boolean型参数表示是否在删除操作邮件后更新Folder
store.close();
贴上本人在实际项目中的实现代码:
Mail.java
/*
* Mail.java:Mail实体
*
* Created on 2009-2-19
*
* Copyright(C) 2009, by Ambow Research&Development Branch.
*
* Original Author: LuFeng
*
* Changes
* -------
* $Log$
*/
package cn.com.ambow.cip.system.facade;
import java.util.Date;
import java.util.Vector;
public class Mail {
private String title; // 主题
private String inceptAddress; //收件人地址
private String sendAddress; //发件人地址
private String content; // 邮件正文
private Vector file=null; //附件
private Date sendTime; // 发送时间
public Mail(){
title="";
inceptAddress="";
sendAddress="";
content="";
file=new Vector();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Vector getFile() {
return file;
}
public void setFile(Vector file) {
this.file = file;
}
public String getInceptAddress() {
return inceptAddress;
}
public void setInceptAddress(String inceptAddress) {
this.inceptAddress = inceptAddress;
}
public String getSendAddress() {
return sendAddress;
}
public void setSendAddress(String sendAddress) {
this.sendAddress = sendAddress;
}
public Date getSendTime() {
return sendTime;
}
public void setSendTime(Date sendTime) {
this.sendTime = sendTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
//该方法用于收集附件名
public void attachfile(String fname){
file.addElement(fname);
}
}
MailFacade.java
/*
* MailFacade.java:本类功能简介
*
* Created on 2009-2-19
*
* Copyright(C) 2009, by Ambow Research&Development Branch.
*
* Original Author: LuFeng
*
* Changes
* -------
* $Log$
*/
package cn.com.ambow.cip.system.facade;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeUtility;
import javax.mail.Multipart;
import javax.mail.internet.MimeMultipart;
import javax.mail.MessagingException;
import javax.activation.FileDataSource;
import javax.activation.DataHandler;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Date;
import cn.com.ambow.publicwork.config.AmbowConfig;
import cn.com.ambow.publicwork.common.AmbowLang;
public class MailFacade {
private static String SMTPServer="";
private static String MailUserName="";
private static String MailPassword="";
private static String SendDebug="";
private static String IsLoad="";
//做一个可以传发件人等参数的构造
public MailFacade() throws Exception{
if(IsLoad.length()==0){ //如果还没有装载,则装载邮件服务器信息(从.properties文件中读取)
AmbowConfig abConfig=AmbowConfig.createAmbowConfig();
SMTPServer=AmbowLang.getEmptyString(abConfig.getProperty("smtpServer"));
MailUserName=AmbowLang.getEmptyString(abConfig.getProperty("username"));
MailPassword=AmbowLang.getEmptyString(abConfig.getProperty("password"));
SendDebug=AmbowLang.getEmptyString(abConfig.getProperty("sendDebug"));
IsLoad="load";
}
}
/**
* 发送邮件方法
* 接收一个Mail对象(封装邮件)
*/
public boolean startSend(Mail mail) throws Exception{
//创建Properties对象
Properties props = System.getProperties();
//创建信件服务器
props.put("mail.debug",SendDebug);
props.put("mail.smtp.host",SMTPServer);
props.put("mail.smtp.auth","true");//执行SMTP验证
MyAuthenticator auth=new MyAuthenticator(MailUserName,MailPassword);
//得到默认的对话对象
Session session=Session.getDefaultInstance(props,auth);
try {
//创建一个消息,并初始化该消息的各项元素
MimeMessage msg = new MimeMessage(session);
//发送人地址
msg.setFrom(new InternetAddress(mail.getSendAddress()));
//收件人地址
InternetAddress[] address={new InternetAddress(mail.getInceptAddress())};
msg.setRecipients(Message.RecipientType.TO,address);
//设置主题
msg.setSubject(AmbowLang.getEmptyString(mail.getTitle()).trim());
//后面的BodyPart将加入到此处创建的Multipart中
Multipart mp = new MimeMultipart();
//邮件正文
MimeBodyPart mbpText=new MimeBodyPart();
mbpText.setContent(AmbowLang.getEmptyString(mail.getContent()),"text/html;charset=gb2312");
mp.addBodyPart(mbpText);
//利用枚举器方便的遍历集合
Enumeration efile=mail.getFile().elements();
//检查序列中是否还有更多的对象
String filename="";
while(efile.hasMoreElements()){
MimeBodyPart mbp=new MimeBodyPart();
//选择出每一个附件名
filename=efile.nextElement().toString();
//得到数据源
FileDataSource fds=new FileDataSource(filename);
//得到附件本身并至入BodyPart
mbp.setDataHandler(new DataHandler(fds));
//得到文件名同样至入BodyPart(同时处理中文文件名)
mbp.setFileName(MimeUtility.encodeWord(fds.getName(),"GB2312",null));
mp.addBodyPart(mbp);
}
//移走集合中的所有元素
mail.getFile().removeAllElements();
//Multipart加入到信件
msg.setContent(mp);
//设置信件头的发送日期
msg.setSentDate(new Date());
//发送信件
Transport.send(msg);
}catch(MessagingException mex){
mex.printStackTrace();
Exception ex = null;
if ((ex=mex.getNextException())!=null){
ex.printStackTrace();
}
return false;
}
return true; //发送成功
}
//SMTP验证类(内部类),继承javax.mail.Authenticator
class MyAuthenticator extends Authenticator {
private String strUser;
private String strPwd;
public MyAuthenticator(String user, String password) {
this.strUser = user;
this.strPwd = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(strUser, strPwd);
}
}
//测试方法
public static void main(String args[])throws Exception{
MailFacade mailFacade=new MailFacade();
Mail mail=new Mail();
mail.setSendAddress("xxx.xxx@ambow.com");
mail.setInceptAddress("xxxxxx@163.com");
mail.setTitle("邮件标题");
mail.setContent("您好:这是邮件正文,谢谢!");
mail.attachfile("D:\\Work\\邮件附件.rar");
System.out.println(mailFacade.startSend(mail));
}
}
本文详细介绍JavaMail技术的基础概念,包括邮件传输协议(SMTP、POP、IMAP)、MIME标准及NNTP协议。此外还介绍了如何使用JavaMail API进行邮件收发,涉及Session、Message、Address等核心类的使用方法。
1363

被折叠的 条评论
为什么被折叠?



