一、JavaMail API简介
JavaMail API是读取、撰写、发送电子信息的可选包。

可用它来建立如Eudora、Foxmail、MS Outlook Express一般的邮件用户代理程序(Mail User Agent,简称MUA,而非邮件传输代理MTA)。
从另外一个角度来看,我们这些电子邮件用户日常用MUA程序来读写邮件,而MUA依赖着MTA处理邮件的递送。

二、相关协议一览
不依赖于协议的方式发送接收电子信息,只依赖特定协议SMTP、POP、IMAP、MIME、NNTP协议。
1.SMTP(递送邮件机制)
简单邮件传输协议
SMTP服务器将邮件转发到接收者的SMTP服务器,直至最后被接收者通过POP或者IMAP协议获取。

2.POP(获取邮件机制)
邮局协议,目前为第3个版本POP3

3.IMAP(多目录共享)
接收信息的高级协议,目前版本为第4版IMAP4

接收新信息,将这些信息递送给用户,维护每个用户的多个目录。

4.MIME
邮件扩展内容格式:信息格式、附件格式等等

5.NNTP

第三方新闻组协议

三、安装
1.安装JavaMail
http://java.sun.com/products/javamail/downloads/index.html下载JavaMail

mail.jar文件添加到CLASSPATH中

2.安装JavaBeans Activation Framework
http://java.sun.com/products/javabeans/glasgow/jaf.html下载JavaBeans Activation Framework

activation.jar文件添加到CLASSPATH中
四、初次认识JavaMail API
1.了解我们的JavaMail环境
A.纵览JavaMail核心类结构
JavaMail.jar文件的一些核心类:Session、Message、Address、Authenticator、Transport、Store、Folder
以及javax.mail.internet包中还有一些常用的子类。
B.Session(邮件会话)
进行收发邮件的工作都是基于这个会话的。
Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);

或者

Properties props = new Properties();
Session session = Session.getInstance(props, null);

从上面的两个例子中不难发现,第二个参数都是null,这是因为在上面的例子中并没有使用到邮件授权(参考E)

C.Message
建立了Session对象后,便可以被发送的构造信息体Message抽象类

使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型、MIME信息头的邮箱信息。
信息头只能使用US-ASCII字符
Message message = new MimeMessage(session);
message.setContent("Hello", "text/plain");//非文本信息内容
message.setText("Hello");//纯文本信息内容
message.setSubject("First");//设置邮件主题
message.setSentDate(Date);//设置邮件发送日期

D.Address
建立了Session和Message对象后,使用邮件地址Address抽象类

使用javax.mail.internet.InternetAddress这个子类。通过传入邮件地址的字符串
Address address = new InternetAddress("kuangye89757@163.com"); //邮件地址
Address address = new InternetAddress("president@whitehouse.gov", "George Bush"); //带名字的邮件地址
message.setFrom(address);//设置发信人
message.setReplyTo(address);//同上
message.addFrom(Address[] address);//添加多个发信人
 
message.addRecipient(type, address)//设置收信人
Message.RecipientType.TO//收信人
Message.RecipientType.CC//抄送人
Message.RecipientType.BCC//暗送人

E.Authenticator授权者类
使用Authenticator抽象类必须实现getPasswordAuthentication()方法(用于存储认证时要用到的用户名、密码)。

并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类。
Properties props = new Properties();
Authenticator auth = new MyAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
/**
 * 自定义邮件授权类
 * @return
 * @throws IOException
 */
public class MyAuthenticator  extends Authenticator {
  public PasswordAuthentication getPasswordAuthentication(String param) {
String username;
String password;
StringTokenizer st = new StringTokenizer(param, ",");
username = st.nextToken();
password = st.nextToken();
return new PasswordAuthentication(username, password);
}
}

F.Transport
发送信息时使用Transport抽象类(实现了SMTP)

Transport.send(MimeMessage message);
 
或者一般用法
当然,方法是多样的。我们也可由Session获得相应协议对应的Transport实例。并通过传递用户名、密码、邮件服务器主机名等参数建立与邮件服务器的连接,并使用sendMessage()方法将信息发送,最后关闭连接:
session.setDebug(true);//监控邮件发送过程
message.saveChanges(); //保存文件
Transport transport = session.getTransport("smtp");//获取实现了SMTP协议的Transport类
transport.connect(host, username, password);//连接服务器
transport.sendMessage(message, message.getAllRecipients());//发送邮件给所有收件人
transport.close();//关闭连接
 
G.Store(存储邮件的服务器)和Folder(目录对象)
Store store = session.getStore("pop3");
store.connect(host, username, password);
 
Folder folder = store.getFolder("INBOX");//POP3协议只有一个名为INBOX的Folder有效
folder.open(Folder.READ_ONLY);//只读方式打开
Message message[] = folder.getMessages();//获得邮件
System.out.println(((MimeMessage)message).getContent());//邮件内容(不包含邮件头)
System.out.println(((MimeMessage)message).writeTo());//邮件内容(含邮件头)
folder.close(true);//若删除邮件则及时更新Folder,关闭
store.close();//关闭

五、使用JavaMail API
1.发送邮件
在获得了Session后,建立并填入邮件信息,在发送邮件之前,我们需要设置SMTP服务器:通过设置Properties的mail.smtp.host属性

 
mail配置文件.properties
String server=xx.xx.xx.xx(服务器)
authUser=XXX
authPasswd=xxxxxx
/**
 * 获得配置文件信息
 * @return
 * @throws IOException
 */
 private static Properties getProp() throws IOException{
  //获得文件存储路径
  ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  InputStream inputStream = classLoader.getResourceAsStream("mail配置文件.properties");
  Properties prop = new Properties();
  prop.load(inputStream);
  return prop;
 }
 
private String from = ...;//发件人
private String to = ...;//收件人
//获取邮件发送服务器及验证用户名和密码
Properties props=getProp();
props.put("mail.smtp.host", host);
//获取Session会话
Session session = Session.getDefaultInstance(props, null);
//创建MIMEMessage
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("Hello JavaMail");
message.setText("Welcome to JavaMail");
//发送邮件
message.saveChanges();
Transport transport = session.getTransport("smtp");
transport.connect(props.getProperty(“server”), props.getProperty(“authUser”), props.getProperty(“authPasswd”));
transport.sendMessage(message, message.getAllRecipients());
transport.close();

2.接收邮件

Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("pop3");
store.connect(props.getProperty(“server”), props.getProperty(“authUser”), props.getProperty(“authPasswd”));
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
Message message[] = folder.getMessages();
for (int i=0, n=message.length; i<n; i++) {
   System.out.println(i + ": " + message[i].getFrom()[0] + " " + message[i].getSubject());
}
folder.close(false);
store.close();
 
3.删除邮件和标志
Flags类的内部类Flag中预定义了一些标志:(POP协议不支持)
如:Flags.Flag.DELETED   
通过访问一个已经打开的Folder对象的getPermanetFlags()方法,它将返回当前被支持的Flags类对象。
删除邮件时,我们可以设置邮件的DELETED标志: 
if(Message.isSet(Flags.Flag.DELETED)){
folder.open(Folder.READ_WRITE);
message.setFlag(Flags.Flag.DELETED, true);//删除邮件
folder.close(true);
}
 
4.回复邮件
MimeMessage reply = (MimeMessage)message.reply(false);//不发送给发件人
reply.setFrom(new InternetAddress("president@whitehouse.gov"));
reply.setText("Thanks");
Transport.send(reply);//回复邮件

6.转发邮件
转发邮件的过程不如前面的回复邮件那样简单,它将建立一个转发邮件,这并非一个方法就能做到。
每个邮件是由多个部分(邮件体MimeBodyPart类对象)组成

这些邮件体包含MimeMultiPart类对象
复制一个邮件内容到另一个邮件的方法是复制它的DataHandler(数据处理者)
 
Message forward = new MimeMessage(session);
forward.setSubject("Fwd: " + message.getSubject());
forward.setFrom(new InternetAddress(from));
forward.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
forward.setContent(multipart);//这里的多媒体对象通过下列方式获得
Transport.send(forward);//转发邮件
 
//创建邮件体对象
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(“内容”,"text/plain;charset=GB2312");
messageBodyPart.setDataHandler(message.getDataHandler());//从邮件中获取DataHandler
 
//创建多媒体对象
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
7.使用附件

A.发送带有附件的邮件
建立一个完整邮件的各个邮件体部分:

第一个部分:邮件内容文字
第二个部分:具有DataHandler的附件
1.若文件作为附件发送建立FileDataSource类型的附件数据源对象
2.若URL作为附件发送建立URLDataSource类型的附件数据源对象
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("Hello JavaMail Attachment");
 
//第一部分(内容)
BodyPart messageBodyPart1 = new MimeBodyPart();
messageBodyPart1.setText("Pardon Ideas");
 
 
//第二部分(文件附件)
BodyPart  messageBodyPart2 = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart2.setDataHandler(new DataHandler(source));
messageBodyPart2.setFileName(filename);
第二种
  MimeBodyPart body = new MimeBodyPart();
   body.attachFile("d:/data.xlsx");
 
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart1);//装填第一部分
multipart.addBodyPart(messageBodyPart2);//装填第二部分
message.setContent(multipart);
Transport.send(message);//发送带有附件的文件
使用servlet实现发送带有附件的邮件注意提交页面form中对编码类型的设置应为multipart/form-data
<form enctype="multipart/form-data"  method=post action="/myservlet"> 
 <input type="file" NAME="thefile">
 <input type="submit" VALUE="Upload">
</form>

B.读取邮件中的附件
读取邮件中带有附件的邮件是多部分组成的,我们必须处理每一个部分获得邮件的内容和附件
BodyPart类提供了getDisposition()方法获得邮件体的部署类型

该部分是附件时返回Part.ATTACHMENTPart.INLINE
 
//获取邮件中的多媒体
Multipart mp = (Multipart)message.getContent();
//循环遍历多媒体,并获取邮件体各部分
for (int i=0, n=multipart.getCount(); i<n; i++) {
Part part = multipart.getBodyPart(i));
//获得邮件体的部署类型
String disposition = part.getDisposition();
if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT) || (disposition.equals(Part.INLINE))) {
saveFile(part.getFileName(), part.getInputStream());
}else if (disposition == null) {
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
//解析过程
} else {
//其他解析过程
}
}
}
 
8.处理HTML邮件
A.发送HTML邮件
设置邮件内容为html代码,并设置内容类型为text/html即可:
String htmlText = "<H1>Hello</H1>" +  "<img src="http://www.jguru.com/images/logo.gif">";
message.setContent(htmlText, "text/html"));

请注意:
在接收邮件时,因为JavaMail API邮件内容视为二进制流。必须使用JEditorPane

if (message.getContentType().equals("text/html")) {

String content = (String)message.getContent();
JFrame frame = new JFrame();
JEditorPane text = new JEditorPane("text/html", content);
text.setEditable(false);
JScrollPane pane = new JScrollPane(text);
frame.getContentPane().add(pane);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.show();
}

B.在邮件中包含图片
将HTML中用到的图片作为邮件附件并使用特殊的cid URL作为图片的引用(Content-ID头的引用)

通过设置图片附件邮件体部分的header中Content-ID为一个随机字符串,
并在HTML中img的src标记中设置为该字符串来完成了图片附件与HTML的关联。
 
String file = ...;
Message message = new MimeMessage(session);
message.setSubject("Embedded Image");
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
 
// 创建邮件体HTML部分
BodyPart messageBodyPart1 = new MimeBodyPart();
String htmlText = "<H1>Hello</H1>" +   "<img src="cid:memememe">";
messageBodyPart1.setContent(htmlText, "text/html");
 
//创建邮件体img部分
BodyPart  messageBodyPart2 = new MimeBodyPart();
DataSource fds = new FileDataSource(file);
messageBodyPart2.setDataHandler(new DataHandler(fds));
messageBodyPart2.setHeader("Content-ID","<memememe>");


// 创建一个关联的多媒体
MimeMultipart multipart = new MimeMultipart("related");
multipart.addBodyPart(messageBodyPart1);
multipart.addBodyPart(messageBodyPart2);
message.setContent(multipart);

9.在邮件中搜索短语
JavaMail API提供了过滤器机制,它被用来建立搜索短语。

使用javax.mail.search包中的SearchTerm抽象类来定义,在定义后我们便可以使用Folder的Search()方法查找邮件:
下面有22个不同的类(继承了SearchTerm类)供我们使用:
AND terms 、OR terms 、NOT terms 、SENT DATE terms、CONTENT terms 、HEADER terms 
实例:在Folder中搜索邮件主题含有“ADV”字符串或者发信人地址为friend@public.com的邮件。
SearchTerm st =   new OrTerm(new SubjectTerm("ADV:"), new FromStringTerm("friend@public.com"));

javaMail 详解的更多相关文章

  1. Quartz 入门详解

    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简单或为运行十个,百个, ...

  2. Spring 3.x jar 包详解 与 依赖关系

    以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...

  3. commons-logging和Log4j 日志管理/log4j.properties配置详解

    commons-logging和Log4j 日志管理 (zz) 什么要用日志(Log)? 这个……就不必说了吧. 为什么不用System.out.println()? 功能太弱:不易于控制.如果暂时不 ...

  4. 常见 jar包详解

        常见 jar包详解 jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周期 ...

  5. Ant 之bulid.xml详解

    ANT build.xml文件详解(一) Ant的概念 可能有些读者并不连接什么是Ant以及入可使用它,但只要使用通过Linux系统得读者,应该知道 make这个命令.当编译Linux内核及一些软件的 ...

  6. Spring详解(一)------概述

    本系列教程我们将对 Spring 进行详解的介绍,相信你在看完后一定能够有所收获. 1.什么是 Spring ? Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开 ...

  7. [转]application.properties详解 --springBoot配置文件

    本文转载:http://blog.csdn.net/lpfsuperman/article/details/78287265###; # spring boot application.propert ...

  8. application.properties详解 --springBoot配置文件【转载】

    # spring boot application.properties配置的各个属性详解 # 该示例文件作为标准提供.(官方文档 翻译过来的) # 还是花了些功夫翻译,各位如果转发,请留下本文地址, ...

  9. Quartz定时任务详解一

    以下是我在应用的的一个基本配置: #---------调度器属性---------------- org.quartz.scheduler.instanceName = TestScheduler o ...

随机推荐

  1. Python 【文件的读写】

    文件读写 A 读取文件 读文件三步:开——读——关.file1 = open('/Users/Ted/Desktop/test/abc.txt','r',encoding='utf-8')第一个参数是 ...

  2. 资源|《美团机器学习实践》PDF+思维导图

    今天再给大家推荐一本由美团算法团队出版的<美团机器学习实践>,下载链接见文末. 美团算法团队由数百名优秀算法工程师组成,负责构建美团这个生活服务互联网大平台的"大脑", ...

  3. PAT(B) 1013 数素数(Java)

    题目链接:1013 数素数 代码 /** * Score: 20 * Run Time: 124ms * @author wowpH * @version 1.0 */ import java.uti ...

  4. 初始STM32

    主要内容: 1.什么是STM32 STM32有什么 STM32怎么选型号 一:什么是STM32 ST— 意法半寻体,是一个公司名,即SOC厂商(ARM是IP厂商,STM32中内核由ARM设计,外设例如 ...

  5. 【动态规划】洛谷2019 OI春令营 - 普及组 作业

    [P1464 Function] [题解] 按照题目意思进行递归即可,但是过程中需要用到记忆化搜索. #include<bits/stdc++.h> using namespace std ...

  6. python __enter__ 与 __exit__的作用,以及与 with 语句的关系(转)

    https://blog.csdn.net/xc_zhou/article/details/80810111 python __enter__ 与 __exit__的作用,以及与 with 语句的关系

  7. react中jsx文件是如何转换成js对象的

    通过在线babel转换器,转换出jsx是如何变成js对象的 jsx文件 加入了正常的标签以及嵌套标签以及方法属性 function hello() { click=()=>{ console.l ...

  8. redis的安装---Linux

    1.下载https://redis.io/download wget http://download.redis.io/releases/redis-4.0.14.tar.gz tar -zxvf r ...

  9. CAN总线上的消息单帧某个信号的值计算(C#)

      public static ulong GetMotorolaSignalValue(byte[] data, int startBit, int bitLength) { ; , j =; i ...

  10. 【前端】安装wampserver提示丢失MSVCR100.dll的解决方法

    先装Visual C++,再装wampserver 下载的时候请注意选择对应的32bit还是64bit的.然后安装. 再安装wamp