每次在网上打印在线生成的表格打印出现在中间,总是出现这个java安全警告,怎么能不显示这个呢?

博客分类:
引用自http://blog.sina.com.cn/s/articlelist__7_1.html
[JavaMail]1 基础
JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。我们可以基于JavaMail开发出类似于Microsoft Outlook的应用程序。
JavaMail包中用于处理电子邮件的核心类是:Session,Message,Address,Authenticator,Store,Transport, Folder等。Session定义了一个基本的邮件会话,它需要从Properties中读取类似于邮件服务器,用户名和密码等信息。
B、javaMail常用类
B .1、Properties
java.util.Properties:JavaMail需要Properties来创建一个session对象。它将寻找字符串&mail.smtp.host&,属性值就是发送邮件的主机,如:
   Properties props = new Properties ();
   props.put(&mail.smtp.host&, &smtp.abcd.com&);//可以换上你的smtp主机名。
B .2、Session
Javax.mail.Session:Session类定义了一个基本邮件会话(session),是Java Mail API最高层入口类。所有其它类都是经由这个session才得以生效。Session对象用Java.util.Properties对象获取信息,如邮件服务器、用户名、密码及整个应用程序中共享的其它信息。
这个Session类代表JavaMail中的一个邮件session。每一个基于JavaMail的应用程序至少有一个session但是可以有任意多的session。Session对象需要知道用来处理邮件的SMTP服务器。为了做到这一点,你可以参照下面的例子用Properties 来创建一个Session 对象
  Session sendMailS
  sendMailSession = Session.getInstance(props, null);
B .3、Message、MimeMessage
Javax.mail.Message、javax.mail.MimeMessage:一旦获得Session对象,就可以继续创建要发送的消息。这由Message类来完成。因为Message是个抽象类,必需用一个子类,多数情况下为 Javax.mail.internet.MimeMessage。MimeMessage是个能理解MIME类型和头的电子邮件消息,正如不同RFC中所定义的。虽然在某些头部域非ASCII字符也能被译码,但Message头只能被限制为用 US-ASCII 字符。
Message对象将存储我们实际发送的电子邮件信息,Message对象被作为一个MimeMessage对象来创建并且需要知道应当选择哪一个JavaMail session。
Message newMessage = new MimeMessage(sendMailSession);
B .4、Transport
Javax.mail.Transport:消息发送的最后一部分是使用Transport类。这个类用协议指定的语言发送消息(通常是SMTP)。它是抽象类,它的工作方式与Session有些类似。仅调用静态send() 方法,就能使用类的缺省版本:Transport.send(message)。或者,读者也可以从针对自己的协议的会话中获得一个特定的实例,传递用户名和密码(如果不必要就不传),发送消息,然后关闭连接。
邮件是既可以被发送也可以被受到。JavaMail使用了两个不同的类来完成这两个功能:Transport和Store。Transport是用来发送信息的,而Store用来收信。
  transport = sendMailSession.getTransport(&smtp&);
用JavaMail Session对象的getTransport方法来初始化Transport。传过去的字符串申明了对象所要使用的协议,如&smtp&。这将为我们省了很多时间。因为JavaMail以境内置了很多协议的实现方法。
注意: JavaMail并不是绝对支持每一个协议,目前支持IMAP、 SMTP和 POP3。
B .5、Store
Javax.mail.Store:Store类实现特定邮件协议上的读、写、监视、查找等操作。通过Javax.mail.Store类可以访问Javax.mail.Folder类。
Store store=s.getSorte(&pop3&);
store.connect(popserver,username,password);
B .6、Folder
Javax.mail.Folder:Folder类用于分级组织邮件,并提供照Javax.mail.Message格式访问email的能力。
Folder folder=store.getFolder(&INBOX&);
folder.open(Folder.READ_ONLY);
B .7、Address、InternetAddress
Javax.mail.Address、Javax.mail.internet.InternetAddress:一旦您创建了Session 和 Message,并将内容填入消息后,就可以用 Address 确定信件地址了。和 Message 一样,Address 也是个抽象类。您用的是 Javax.mail.internet.InternetAddress 类。
B .8、Authenticator
Javax.mail. 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 对象返回给调用程序。
B .9、Multipart、MimeMultpart
javax.mail.Multipart、javax.mail.Internet.MimeMultpart:一般保存电子邮件内容的容器是Multipart抽象类,它定义了增加和删除及获得电子邮件不同部分内容的方法。由于Multipart是抽象类,我们必须为它使用一个具体的子类,JavaMail API提供javax.mail.Internet.MimeMultpart类来使用MimeMessage对象。
MimeMultipart multipart=new MimeMultipart();
注:我们使用MimeMultipart对象的一个方法是addBodyPart(),它在我们的电子邮件内容里添加BodyPart对象。消息可以有很多部分,一个BodyPart可以代表一个部分。
B .10、BodyPart 、MimeBodyPart
javax.mail.BodyPart、javax.mail.Internet.MimeBodyPart:MimeBodyPart是BodyPart具体用于mimeMessage的一个子类。MimeBodyPart对象代表一个MimeMessage对象内容的一部分。每个MimeBodyPart被认为有两部分:MIME类型和匹配这个类型的内容
MimeBodyPart mdp=new MimeBodyPart();
String text=&Hello JavaMail!&;
mdp.setContent(text,&text/plain&);
//定义MIME类型为text/plain,并设置MimeBodyPart的内容
C.1、通过SMTP发送一封邮件
package com.
import java.util.D
import java.util.P
import javax.mail.M
import javax.mail.M
import javax.mail.S
import javax.mail.T
import javax.mail.internet.InternetA
import javax.mail.internet.MimeBodyP
import javax.mail.internet.MimeM
import javax.mail.internet.MimeM
public class SimpleSender {
public static void main(String args[]) {
String smtpServer = &192.168.1.254&;
String to = &&;
String from = &&;
String subject = &test mail&;
String body = &test mail&;
String msgAttachment = &This is an attachment string!&;
send(smtpServer, to, from, subject, body, msgAttachment);
} catch (Exception ex) {
System.out.println(ex.toString());
System.exit(0);
// 发送一封简单的邮件
public static void send(String smtpServer, String to, String from,
String subject, String body) {
Properties props = System.getProperties();
props.put(&mail.smtp.host&, smtpServer);
Session session = Session.getDefaultInstance(props, null);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
// 发件人地址
InternetAddress[] address = { new InternetAddress(to) };
msg.setRecipients(Message.RecipientType.TO, address);
// 收件人地址,可以是一个或多个。
msg.setSubject(subject);
// 邮件主题
msg.setSentDate(new Date());
// 发送时间
msg.setText(body);
// 邮件正文的内容
msg.setHeader(&X-Mailer&, &LOTONtechEmail&);
Transport.send(msg);
System.out.println(&Message sent OK.&);
} catch (Exception ex) {
ex.printStackTrace();
// 发送一封带有附件的邮件
public static void send(String smtpServer, String to, String from,
String subject, String body, String msgAttachment) {
Properties props = System.getProperties();
props.put(&mail.smtp.host&, smtpServer);
Session session = Session.getDefaultInstance(props, null);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = { new InternetAddress(to) };
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject(subject);
msg.setSentDate(new Date());
msg.setHeader(&X-Mailer&, &LOTONtechEmail&);
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(body);
// 把前面定义的msgText中的文字设定为邮件正文的内容
MimeBodyPart mbp2 = new MimeBodyPart();
mbp2.setText(msgAttachment, &utf-8&);
// 创建附件部分
Multipart mp = new MimeMultipart();
// 创建Multipart
mp.addBodyPart(mbp1);
mp.addBodyPart(mbp2);
// 把前面定义的正文和附件都添加到Multipart中
msg.setContent(mp);
// 添加 Multipart到Message中
Transport.send(msg);
System.out.println(&Message sent OK.&);
} catch (Exception ex) {
ex.printStackTrace();
[JavaMail]2 身份验证
Authenticator
Authenticator (Javax.mail.Authenticator):JavaMail利用Authenticator通过用户名和密码访问受保护的资源。对于JavaMail API来说,这些资源就是邮件服务器。
要使用Authenticator,先创建一个抽象类的子类(extends Authenticator),在子类中覆盖父类中的 getPasswordAuthentication() 方法,就可以实现以不同的方式来进行登录邮箱时的用户身份认证。JavaMail 中的这种设计是使用了策略模式(Strategy),具体的请参看相关文章。创建完成后,您必需向session注册Authenticator。然后,在需要认证的时候,就会通知Authenticator。
下面例子,我们设计了一种简单的 SimpleAuthenticator 子类通过构造函数传入用户名和密码,而另一种 GUIAuthenticator 子类则使用 GUI 界面的形式进行身份认证,它可以使得程序在运行时弹出输入对话框来让用户提交用户名和密码。
package com.
import java.util.D
import java.util.P
import java.util.StringT
import javax.mail.A
import javax.mail.PasswordA
import javax.mail.S
import javax.mail.T
import javax.mail.internet.InternetA
import javax.mail.internet.MimeM
import javax.mail.internet.MimeMessage.RecipientT
import javax.swing.JOptionP
// 创建抽象类Authenticator的子类,SimpleAuthenticator通过构造函数传入身份验证信息
class SimpleAuthenticator extends Authenticator {
public SimpleAuthenticator(String user, String pwd) {
this.user =
this.pwd =
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pwd);
// 通过弹出输入对话框传入身份验证信息
class GUIAuthenticator extends Authenticator {
protected PasswordAuthentication getPasswordAuthentication() {
// 弹出输入对话框
String result = JOptionPane.showInputDialog(&请输入用户名和密码,以','隔开!&);
StringTokenizer st = new StringTokenizer(result, &,&);
user = st.nextToken();
pwd = st.nextToken();
return new PasswordAuthentication(user, pwd);
public class UseAuthenticatorSender {
private String smtpServer = &192.168.1.254&;
private String from = &&;
private String to = &&;
private String subject = &使用Authenticator子类进行用户身份认证&;
private String body = &使用Authenticator子类进行用户身份认证的测试!&;
public void sendMails(Authenticator auth) throws Exception {
// 设置协议、是否身份验证、服务器等信息
Properties props = new Properties();
props.setProperty(&mail.transport.protocol&, &smtp&);
// 指定发送邮件协议
props.setProperty(&mail.smtp.auth&, &true&);
// 向SMTP服务器提交用户认证
props.setProperty(&mail.host&, smtpServer);
// SMTP服务器主机地址
Session session = Session.getInstance(props, auth);
// 通过传入的参数获得Authenticator子类对象
session.setDebug(true);
// 调试模式
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
msg.setRecipient(RecipientType.BCC, new InternetAddress(to));
msg.setSubject(subject);
msg.setSentDate(new Date());
msg.setText(body);
msg.saveChanges();
Transport.send(msg);
public static void main(String[] args) throws Exception {
UseAuthenticatorSender sender = new UseAuthenticatorSender();
// 这里体现了使用策略模式的好处,客户端可以选择使用
// 具体的哪一种身份验证方式来提交信息
// Authenticator auth = new SimpleAuthenticator(&xxx&, &xxxx&);
Authenticator auth = new GUIAuthenticator();
sender.sendMails(auth);
[JavaMail]3 接收、处理邮件
接收邮件可以应用协议(POP3或IMAP)。
A.1、接收邮件过程
参考下面例子中showMessages()
1.Store(Javax.mail.Store)
接收邮件和发送邮件很类似都要用到Session。但是在获得Session后,我们需要从Session中获取特定类型的Store,然后连接到Store,这里的Store代表了存储邮件的邮件服务器。在连接Store的过程中,极有可能需要用到用户名、密码或者Authenticator。
Store store = session.getStore(&imap&);
Store store = session.getStore(&pop3&);
store.connect(host, username, password);
2.Folder(Javax.mail.Folder)
在连接到Store后,一个Folder对象即目录对象将通过Store的getFolder()方法被返回,我们可从这个Folder中读取邮件信息:
Folder folder = store.getFolder(&INBOX&);
folder.open(Folder.READ_ONLY);
上面的例子首先从Store中获得INBOX这个Folder(对于POP3协议只有一个名为INBOX的Folder有效),然后以只读(Folder.READ_ONLY)的方式打开Folder,
注意:对于POP3协议只有一个名为INBOX的Folder有效,而对于IMAP协议,我们可以访问多个Folder。
3.Message (Javax.mail.Message)
最后调用Folder的getMessages()方法得到目录中所有Message的数组。
Message message[] = folder.getMessages();
Folder的getMessages()方法时采取了很智能的方式:首先接收新邮件列表,然后再需要的时候(比如读取邮件内容)才从邮件服务器读取邮件内容。在读取邮件时,我们可以用Message类的getContent()方法接收邮件或是writeTo()方法将邮件保存,getContent()方法只接收邮件内容(不包含邮件头),而writeTo()方法将包括邮件头。
((MimeMessage)message).getContent();
4.关闭连接
在读取邮件内容后,别忘记了关闭Folder和Store。
folder.close(Boolean);
store.close();
传递给Folder.close()方法的boolean 类型参数表示是否在删除操作邮件后更新Folder。
A.2、查看邮件数、新邮件和未读邮件
参考下面例子中showFolderInfo()
想知道邮箱中共有多少邮件、有多少邮件读过和有多少邮件没有读过。
Folder对象提供了三个方法。GetMessageCount方法显示邮箱中总共有多少封信,getNewMessageCount显示邮箱中新邮件的封数,getUnreadMessageCount显示邮箱中未读邮件的封数。
注意:对于POP3协议,只支持GetMessageCount查询邮件总数。不支持判断邮件的未读和新邮件标记,只有自己进行判断操作了。
A.3、消息标识(删除邮件)
消息的删除涉及使用与消息相关的 Flags(标志)。不同 flag 对应不同的状态,有些由系统定义而有些则由用户定义。下面列出在内部类 Flags.Flag 中预定义的标志:
* Flags.Flag.ANSWERED
* Flags.Flag.DELETED
* Flags.Flag.DRAFT
* Flags.Flag.FLAGGED
* Flags.Flag.RECENT
* Flags.Flag.SEEN
* Flags.Flag.USER
仅仅因为存在一个标志,并不意味着所有邮件服务器或供应商都支持这个标志。例如,除了删除消息标志外,POP 协议不再支持其它任何标志。检查是否存在新邮件,这也不是个POP任务,而是内建于邮件客户机的任务。为找出哪些标志能被支持,可以用 getPermanentFlags() 向 folder 提出要求。
消息标识的应用删除邮件
参考下面例子中deleteMessage()
要删除消息,您可以设置消息的 DELETED flag:
message.setFlag(Flags.Flag.DELETED, true);
首先,请以 READ_WRITE 模式打开 folder:
folder.open(Folder.READ_WRITE);
然后,当所有消息的处理完成后,关闭 folder,并传递一个 true 值,从而擦除(expunge)有 delete 标志的消息。
folder.close(true);
一个 Folder 的 expunge() 方法可以用来删除消息。但Sun的POP3供应商不支持。其它供应商有的或许能够实现这一功能,而有的则不能。IMAP供应商极有可能实现此功能。因为 POP只支持单个对邮箱的访问,对Sun的供应商来说,您必需关闭folder以删除消息。
要取消标志,只要传递false给setFlag()方法就行了。想知道是否设置过标志,可以用 isSet() 检查。
A.4、复制或移动邮件
参考下面例子中moveMessage()
Folder类的copyMessages(Message[] msgs, Folder folder);方法可实现复制邮件的功能。参数msgs为你要复制的邮件数组。参数folder为你要复制的目的邮件箱。该操作是复制邮件,把原邮件删除,则实现移动邮件。
package com.
import java.io.BufferedR
import java.io.InputS
import java.io.InputStreamR
import java.util.P
import javax.mail.A
import javax.mail.F
import javax.mail.F
import javax.mail.M
import javax.mail.M
import javax.mail.P
import javax.mail.S
import javax.mail.S
import javax.mail.internet.InternetA
public class TreatMessages {
private String smtpServer = &192.168.1.254&;
// 连接Session
private Session getSession() {
Session session =
Authenticator auth = new SimpleAuthenticator(&xx&, &xx&);
// 身份验证,SimpleAuthenticator在UseAuthenticatorSender中定义。
Properties props = new Properties();
props.setProperty(&mail.transport.protocol&, &smtp&);
props.setProperty(&mail.smtp.auth&, &true&);
props.setProperty(&mail.host&, smtpServer);
session = Session.getInstance(props, auth);
// session.setDebug(true);
} catch (Exception ex) {
System.out.println(ex.toString());
// 显示所有邮件
public void showMessages() {
Session session = getSession();
Store store = session.getStore(&pop3&);
store.connect();
// 以pop3协议连接到Store。port:25
Folder folder =
folder = store.getDefaultFolder();
if (folder == null)
throw new Exception(&No default folder&);
// 获取默认文件夹
folder = folder.getFolder(&INBOX&);
if (folder == null)
throw new Exception(&No POP3 INBOX&);
// 如果是收件箱
folder.open(Folder.READ_WRITE);
// 使用读写方式打开收件箱
Message[] msgs = folder.getMessages();
// 得到文件夹信息,获取邮件列表
for (int msgNum = 0; msgNum & msgs. msgNum++) {
printMessage(msgs[msgNum]);
// 显示所有邮件信息。
folder.close(true);
// 参数表示是否在删除操作邮件后更新Folder
store.close();
// 关闭store。
} catch (Exception ex) {
System.out.println(ex.toString());
// 打印邮件信息
public static void printMessage(Message message) {
String from = ((InternetAddress) message.getFrom()[0])
.getPersonal();
if (from == null)
from = ((InternetAddress) message.getFrom()[0]).getAddress();
System.out.println(&FROM: & + from);
// 获得发送邮件地址
String subject = message.getSubject();
System.out.println(&SUBJECT: & + subject);
// 获取主题
Part messagePart =
Object content = messagePart.getContent();
// 获取信息对象
if (content instanceof Multipart) {
messagePart = ((Multipart) content).getBodyPart(0);
System.out.println(&[ Multipart Message ]&);
String contentType = messagePart.getContentType();
System.out.println(&CONTENT:& + contentType);
// 获取content类型
if (contentType.startsWith(&text/plain&)
|| contentType.startsWith(&text/html&)) {
InputStream is = messagePart.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String thisLine = reader.readLine();
while (thisLine != null) {
System.out.println(thisLine);
thisLine = reader.readLine();
// 如果邮件内容是纯文本或者是HTML,那么打印出信息
System.out.println(&-----------------------------&);
} catch (Exception ex) {
ex.printStackTrace();
// 删除收件箱的第一封邮件
public void deleteMessage() {
Session session = getSession();
Store store = session.getStore(&pop3&);
store.connect();
Folder folder =
folder = store.getDefaultFolder();
if (folder == null)
throw new Exception(&No default folder&);
folder = folder.getFolder(&INBOX&);
if (folder == null)
throw new Exception(&No POP3 INBOX&);
folder.open(Folder.READ_WRITE);
Message[] msgs = folder.getMessages();
Message message = msgs[0];
// 获取第一封邮件
message.setFlag(Flags.Flag.DELETED, true);
if (message.isSet(Flags.Flag.DELETED))
System.out.println(&这封信已被删除,请返回!&);
// 删除这一封邮件
folder.close(true);
// 参数表示是否在删除操作邮件后更新Folder
store.close();
} catch (Exception ex) {
System.out.println(ex.toString());
// 以imap协议连接,显示邮箱状况
public void showFolderInfo() {
Session session = getSession();
Store store = session.getStore(&imap&);
// 以imap协议连接到Store,port:143。
// pop3不支持判断邮件的已读、未读和新邮件标记,只有自己进行判断操作。
store.connect();
Folder folder =
folder = store.getDefaultFolder();
if (folder == null)
throw new Exception(&No default folder&);
folder = folder.getFolder(&INBOX&);
if (folder == null)
throw new Exception(&No POP3 INBOX&);
folder.open(Folder.READ_ONLY);
// 以只读方式打开邮件夹
int numberOfTotal = folder.getMessageCount();
// 取得邮箱中总共有多少封信
int numberOfUnread = folder.getUnreadMessageCount();
// 取得邮箱中未读邮件
int numberOfNew = folder.getNewMessageCount();
// 取得邮箱中新邮件
System.out.println(&您的邮箱中共有& + numberOfTotal
+ &封邮件,其中有&+ numberOfUnread + &封未读邮件&
+ &,有& + numberOfNew + &封新邮件&);
folder.close(true);
store.close();
} catch (Exception ex) {
System.out.println(ex.toString());
// 移动邮件
public void moveMessage() {
Session session = getSession();
Store store =
IMAPFolder folder =
Folder to_folder =
// 获取存储
store = session.getStore(&imap&);
// 连接邮箱服务器
store.connect();
// 获取收件箱文件夹
folder = (IMAPFolder) store.getFolder(&INBOX&);
// 以可读可写方式打开邮箱文件夹
folder.open(Folder.READ_WRITE);
to_folder = store.getFolder(&Trash&);
// 为了简单起见,移动第1封邮件
Message[] messages = folder.getMessages();
Message[] needCopyMsgs = new Message[1];
needCopyMsgs[0] = messages[0];
// 将获取的邮件对象复制到其他文件夹中
folder.copyMessages(needCopyMsgs, to_folder);
// 移动意味着要把收件箱中原有的邮件删除
messages[0].setFlag(Flags.Flag.DELETED, true);
// 如果文件夹不为空且已经打开就将其关闭
if (folder != null && folder.isOpen()) {
folder.close(true);
// 如果其他文件夹不为空着将其关闭
if (to_folder != null && to_folder.isOpen()) {
to_folder.close(true);
// 如果存储为空且已经打开就将其关闭
if (store != null && store.isConnected()) {
store.close();
} catch (Exception ex) {
System.out.println(ex.toString());
public static void main(String[] args) throws Exception {
TreatMessages treat = new TreatMessages();
treat.showFolderInfo();
[JavaMail]4 处理附件
邮件中的附件,不得不说一说Multipart类,Multipart类是Message类的子类,提供了在邮件中加入附加的实现方法。一个多部分邮件是一个内容类型(content-type)被设置为multipart的Message对象。Multipart类是一个容器类,包含Bodypart类型的对象。Bodypart对象是一个Part接口的实例,它既包括一个新的Multipart容器对象,又包括一个DataHandler对象。
A.1、邮件附件操作需要用到的类
Multipart、MimeMultpart
javax.mail.Multipart、javax.mail.Internet.MimeMultpart:一般保存电子邮件内容的容器是Multipart抽象类,它定义了增加和删除及获得电子邮件不同部分内容的方法。由于Multipart是抽象类,我们必须为它使用一个具体的子类,JavaMail API提供javax.mail.Internet.MimeMultpart类来使用MimeMessage对象。
MimeMultipart multipart=new MimeMultipart();
注:我们使用MimeMultipart对象的一个方法是addBodyPart(),它在我们的电子邮件内容里添加BodyPart对象。消息可以有很多部分,一个BodyPart可以代表一个部分。
BodyPart 、MimeBodyPart
javax.mail.BodyPart、javax.mail.Internet.MimeBodyPart:MimeBodyPart是BodyPart具体用于mimeMessage的一个子类。MimeBodyPart对象代表一个MimeMessage对象内容的一部分。每个MimeBodyPart被认为有两部分:MIME类型和匹配这个类型的内容
MimeBodyPart mdp=new MimeBodyPart();
String text=&Hello JavaMail!&;
mdp.setContent(text,&text/plain&);
//定义MIME类型为text/plain,并设置MimeBodyPart的内容
DataHandler
javax.activation.DataHandler:JavaMail API不限制信息只为文本,任何形式的信息都可能作为MimeMessage的一部分。除了文本信息,作为文件附件包含在电子邮件信息的一部分是很普遍的。JavaMail API通过使用DataHandler对象,提供一个允许我们包含非文本BodyPart对象的简便方法。
DataHandler dh=new DataHandler(text,type);
mdp.setDatahandler(dh);
//mdp是一个MimeBodyPart对象
FileDataSource
javax.activation.FileDataSource:一个FileDataSource对象可以表示本地文件和服务器可以直接访问的资源。一个本地文件可以通过创建一个新的MimeBodyPart对象附在一个mimeMessage对象上。
MimeBodyPart mdp=new MimeBodyPart();
FileDataSource fds=new FileDataSource(&c:/exam.txt&);
mdp.setDataHandler(new DataHandler(fds)); //设置数据源
URLDataSource
javax.activation.URLDataSource:远程资源,URL不会指向它们,由一个URLDataSource对象表示。一个远程资源可以通过创建一个新mimeBodyPart对象附在一个mimeMessage对象上(同FileDataSource差不多)。
URLDataSource uds=new URLDataSource(&http://www.cnjsp.com/logo.gif&);
//与FileDataSource唯一不同的是数据源的设置
A.2、应用说明
发送三种不同类型的附件
参考sendAttachment()
信件内容和附件都作为一个BodyPart添加到Multipart中。再把Multipart添加到Message中。
三种不同类型的附件为:
1.直接将所设文本内容加到自定义文件中作为附件发送
2.用本地上的文件作为附件
3.用远程文件作为附件
把邮件中附件下载下来
参考getAttachment()
邮件Message包括Header和Body两部分,用message.getContent()从Message中获得邮件的Body部分,邮件的Body部分是一个Multipart对象,由一个或多个Part对象组成,再Multipart.getBodyPart(i)获取Part对象,进行判断过后下载其中的附件。
package com.
import java.io.FileOutputS
import java.io.InputS
import java.net.URL;
import java.util.D
import java.util.P
import javax.activation.DataH
import javax.activation.FileDataS
import javax.activation.URLDataS
import javax.mail.A
import javax.mail.BodyP
import javax.mail.F
import javax.mail.M
import javax.mail.M
import javax.mail.P
import javax.mail.S
import javax.mail.S
import javax.mail.T
import javax.mail.internet.InternetA
import javax.mail.internet.MimeBodyP
import javax.mail.internet.MimeM
import javax.mail.internet.MimeM
public class TreatAttachment {
private String smtpServer = &192.168.1.254&;
private String filePath=&C:/&;
// 连接Session
private Session getSession() {
Session session =
Authenticator auth = new SimpleAuthenticator(&x&, &x&);
// 身份验证,SimpleAuthenticator在UseAuthenticatorSender中定义。
Properties props = new Properties();
props.setProperty(&mail.transport.protocol&, &smtp&);
props.setProperty(&mail.smtp.auth&, &true&);
props.setProperty(&mail.host&, smtpServer);
session = Session.getInstance(props, auth);
// session.setDebug(true);
} catch (Exception ex) {
System.out.println(ex.toString());
public void getAttachment() {
Session session = getSession();
Store store = session.getStore(&pop3&);
store.connect();
Folder folder =
folder = store.getDefaultFolder();
if (folder == null)
throw new Exception(&No default folder&);
folder = folder.getFolder(&INBOX&);
if (folder == null)
throw new Exception(&No POP3 INBOX&);
folder.open(Folder.READ_WRITE);
Message[] messages = folder.getMessages();
int n = 0;
Message message = messages[n];
// 为了简单起见,我默认第1封信为有附件的邮件
Multipart mp = (Multipart) message.getContent();
// 获取邮件内容,放到Multipart中
int partCount = mp.getCount();
// 从Multipart获取BodyPart的数量
for (int i = 0; i & partC i++) {
Part part = mp.getBodyPart(i);
//从Multipart获取BodyPart
storeFile(part);
folder.close(true);
store.close();
} catch (Exception ex) {
System.out.println(ex.toString());
//保存附件
public void storeFile(Part part){
if (part.isMimeType(&text/plain&)){
System.out.println(&This is plain text& );
}else if (part.isMimeType(&multipart
BodyPart mdp = new MimeBodyPart();
// 新建一个存放信件内容的BodyPart对象
mdp.setContent(tcontent, &text/charset=gb2312&);
// 给BodyPart对象设置内容和格式/编码方式
mm.addBodyPart(mdp);
// 将含有信件内容的BodyPart加入到MimeMultipart对象中
mdp = new MimeBodyPart();
// 新建一个存放附件的BodyPart
DataHandler dh = new DataHandler(&JavaMail附件测试&,
&text/charset=gb2312&);
// 新建一个DataHandler对象,并设置其内容和格式/编码方式
mdp.setFileName(&xxf.txt&);
// 加上这句将作为附件发送,否则将作为信件的文本内容
mdp.setDataHandler(dh);
// 给BodyPart对象设置内容为DataHandler
mm.addBodyPart(mdp);
mdp = new MimeBodyPart();
FileDataSource fds = new FileDataSource(&c:/passwd.xls&);
dh = new DataHandler(fds);
mdp.setFileName(&passwd.xls&);
// 可以和原文件名不一致
mdp.setDataHandler(dh);
mm.addBodyPart(mdp);
mdp = new MimeBodyPart();
URLDataSource ur = new URLDataSource(
new URL(&http://xx/1_01.gif&));
// 注:这里用的参数只能为URL对象,不能为URL字串,
//在前面类介绍时有误(请谅解),这里纠正一下.
dh = new DataHandler(ur);
mdp.setFileName(&1_01.gif&);
mdp.setDataHandler(dh);
mm.addBodyPart(mdp);
msg.setContent(mm);
// 把mm作为消息对象的内容, 添加到Message中。
msg.saveChanges();
Transport.send(msg);
System.out.println(&Message sent OK.&);
} catch (Exception ex) {
ex.printStackTrace();
public static void main(String[] args) throws Exception {
TreatAttachment treat = new TreatAttachment();
treat.getAttachment();
[JavaMail]5 常用类详解
1.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
SMTP服务器地址,如smtp.sina.com.cn
mail.stmp.port
SMTP服务器端口号,默认为25
mail.stmp.auth
SMTP服务器是否需要用户认证,默认为false
mail.stmp.user
SMTP默认的登陆用户名
mail.stmp.from
默认的邮件发送源地址
mail.stmp.socketFactory.class
socket工厂类类名,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.net.SocketFactory接口
mail.stmp.socketFactory.port
指定socket工厂类所用的端口号,如果没有规定,则使用默认的端口号
mail.smtp.socketFactory.fallback
设置为true时,当使用指定的socket类创建socket失败后,将使用java.net.Socket创建socket,默认为true
mail.stmp.timeout
I/O连接超时时间,单位为毫秒,默认为永不超时
其他几个协议也有类似的一系列属性,如POP3的mail.pop3.host、mail.pop3.port以及IMAP的mail.imap.host、mail.imap.port等。
更详细的信息请查看com.sun.mail.smtp、com.sun.mail.pop3和com.sun.mail.imap这三个包的Javadoc:http://java.sun.com/products/javamail/javadocs/index.html。
2.Session(会话对象)
Session是一个很容易被误解的类,这归咎于混淆视听的类名。千万不要以为这里的Session像HttpSession一样代表真实的交互会话,但创建Session对象时,并没有对应的物理连接,它只不过是一对配置信息的集合。Session的主要作用包括两个方面:
1.接收各种配置属性信息:通过Properties对象设置的属性信息;
2.初始化JavaMail环境:根据JavaMail的配置文件,初始化JavaMail环境,以便通过Session对象创建其他重要类的实例。
所以,如果把Session更名为Configure也许更容易理解一些。
Session通过JavaMail配置文件以及程序中设置的Properties对象构建一个邮件处理环境,后续的处理将在Session基础上进行。Session拥有多个静态工厂方法用于创建Session实例。getInstance方法
1.static Session getDefaultInstance(Properties props, Authenticator authenticator):当JVM中已经存在默认的Session实例中,直接返回这个实例,否则创建一个新的Session实例,并将其作为JVM中默认Session实例。这个API很诡异,我们将对它进行详细的讲解。由于这个默认Session实例可以被同一个JVM所有的代码访问到,而Session中本身又可能包括密码、用户名等敏感信息在内的所有属性信息,所以后续调用也必须传入和第一次相同的Authenticator实例,否则将抛出java.lang.SecurityException异常。如果第一次调用时Authenticator入参为null,则后续调用通过null的Authenticator入参或直接使用getDefaultInstance(Properties props)即可返回这个默认的Session实例。值得一提的是,虽然后续调用也会传入Properties,但新属性并不会起作用,如果希望采用新的属性值,则可以通过getDefaultInstance(Properties props)创建一个新的Session实例达到目的。Authenticator在这里承当了两个功能:首先,对JVM中默认Session实例进行认证保护,后续调用执行getDefaultInstance(Properties props, Authenticator authenticator)方法时必须和第一次一样;其次,在具体和邮件服务器交互时,又作为认证的信息;
2.static Session getDefaultInstance(Properties props):返回JVM中默认的Session实例,如果第一次创建Session未指定Authenticator入参,后续调用可以使用该访问获取S
3.static Session getInstance(Properties props, Authenticator authenticator):创建一个新的Session实例,它不会在JVM中被作为默认实例共享;
4.static Session getInstance(Properties props):根据相关属性创建一个新的Session实例,未使用安全认证信息;
Session是JavaMail提供者配置文件以及设置属性信息的“容器”,Session本身不会和邮件服务器进行任何的通信。所以在一般情况下,我们仅需要通过getDefaultInstance()获取一个共享的Session实例就可以了,下面的代码创建了一个Session实例:
Properties props = System.getProperties();
props.setProperty(&mail.transport.protocol&, &smtp&);
Session session = Session.getDefaultInstance(props);
注意:要观察传到邮件服务器上的邮件命令,请用 session.setDebug(true) 设置调试标志。
3.Transport和Store(传输和存储)
邮件操作只有发送或接收两种处理方式,JavaMail将这两种不同操作描述为传输(javax.mail.Transport)和存储(javax.mail.Store),传输对应邮件的发送,而存储对应邮件的接收。
Session提供了几个用于创建Transport和Store实例的方法,在具体讲解这些方法之前,我们事先了解一下Session创建Transport和Store的内部机制。我们知道提供者在javamail.providers配置文件中为每一种支持的邮件协议定义了实现类,Session根据协议类型(stmp、pop3等)和邮件操作方式(传输和存储)这两个信息就可以定位到一个实例类上。比如,指定stmp协议和transport类型后,Session就会使用com.sun.mail.smtp.SMTPTransport实现类创建一个Transport实例,而指定pop3协议和store类型时,则会使用com.sun.mail.pop3.POP3Store实例类创建一个Store实例。Session提供了多个重载的getTransport()和getStore()方法,这些方法将根据Session中Properties属性设置情况进行工作,影响这两套方法工作的属性包括:
mail.transport.protocol
默认的邮件传输协议,例如,smtp
mail.store.protocol
默认的存储邮件协议,例如:pop3
默认的邮件服务地址,例如:192.168.67.1
默认的登陆用户名,例如:zapldy
下面,我们再回头来了解Session的getTransport()和getStore()的重载方法。
Transport的getTransport()方法
1.Transport getTransport():当Session实例设置了mail.transport.protocol属性时,该方法返回对应的Transport实例,否则抛出javax.mail.NoSuchProviderException。
2.Transport getTransport(String protocol):如果Session没有设置mail.transport.protocol属性,可以通过该方法返回指定类型的Transport,如transport = session.getTransport(“smtp”)。
如果Session中未包含Authenticator,以上两方法创建的Transport实例和邮件服务器交互时必须显示提供用户名/密码的认证信息。如果Authenticator非空,则可以在和邮件服务器交互时被作为认证信息使用。
除了以上两种提供认证信息的方式外,Session还可以使用以下的方法为Transport提供认证信息。
3.Transport getTransport(URLName url):用户可以通过URLName入参指定邮件协议、邮件服务器、端口、用户名和密码信息,请看下面的代码:
URLName urln = new URLName(“smtp”, “smtp.sina.com.cn”, 25, null, “masterspring2”, “spring”);
Transport transport = session.getTransport(urln);
/ * 这里,指定了邮件协议为smtp,邮件服务器是smtp.sina.com.cn,端口为25,用户名/
* 密码为masterspring2/spring。*/
消息发送的最后一部分是使用
Transport 类。这个类用协议指定的语言发送消息(通常是 SMTP)。它是抽象类,它的工作方式与 Session 有些类似。仅调用静态 send() 方法,就能使用类的缺省版本:
Transport.send(message);
或者,您也可以从针对您的协议的会话中获得一个特定的实例,传递用户名和密码(如果不必要就不传),发送消息,然后关闭连接。
message.saveChanges();
Transport transport = session.getTransport(&smtp&);
transport.connect(host, username, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
后面这种方法在您要发送多条消息时最好,因为它能保持邮件服务器在消息间的活动状态。基本send()机制为每个方法的调用设置与服务器独立的连接。
用 Session 获取消息与发送消息开始很相似。但是,在 session 得到后,很可能使用用户名和密码或使用 Authenticator 连接到一个 Store。类似于 Transport ,您告知 Store 使用什么协议:
// Store store = session.getStore(&imap&);
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,还可以用其它文件夹。
注意:Sun 的供应商有意变得聪明。虽然 Message message[] = folder.getMessages(); 看上去是个很慢的操作,它从服务器上读取每一条消息,但仅在你实际需要消息的一部分时,消息的内容才会被检索。
一旦有了要读的 Message,您可以用 getContent() 来获取其内容,或者用 writeTo() 将内容写入流。getContent() 方法只能得到消息内容,而 writeTo() 的输出却包含消息头。
System.out.println(((MimeMessage)message).getContent());
一旦读完邮件,要关闭与 folder 和 store 的连接。
folder.close(aBoolean);
store.close();
传递给 folder 的 close() 方法的 boolean 表示是否清除已删除的消息从而更新 folder。
4.Message(消息对象)
一旦获得Session对象,就可以继续创建要发送的消息。这由Message类来完成。因为 Message是个抽象类,您必需用一个子类,多数情况下为javax.mail.internet.MimeMessage。MimeMessage是个能理解MIME类型和头的电子邮件消息,正如不同RFC中所定义的。虽然在某些头部域非ASCII字符也能被译码,但Message头只能被限制为用US-ASCII字符。
要创建一个 Message,请将 Session 对象传递给 MimeMessage 构造器:
MimeMessage message = new MimeMessage(session);
注意:还存在其它构造器,如用按 RFC822 格式的输入流来创建消息。
一旦获得消息,您就可以设置各个部分,因为Message实现Part接口(且MimeMessage实现MimePart)。设置内容的基本机制是setContent()方法,同时使用参数,分别代表内容和 mime类型:
message.setContent(&Hello&, &text/plain&);
但如果,您知道您在使用MimeMessage,而且消息是纯文本格式,您就可以用setText()方法,它只需要代表实际内容的参数,(MIME 类型缺省为 text/plain):
message.setText(&Hello&);
后一种格式是设置纯文本消息内容的首选机制。至于发送其它类型的消息,如HTML文件格式的消息,我们首选前者。
用 setSubject() 方法设置 subject(主题):
message.setSubject(&First&);
5.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
如果消息是发给副总统的,同时发送一个副本(carbon copy)给总统夫人,以下做法比较恰当:
Address toAddress = new InternetAddress(&vice.president@whitehouse.gov&);
Address ccAddress = new InternetAddress(&first.lady@whitehouse.gov&);
message.addRecipient(Message.RecipientType.TO, toAddress);
message.addRecipient(Message.RecipientType.CC, ccAddress);
JavaMail API 没有提供电子邮件地址有效性核查机制。虽然通过编程,自己能够扫描有效字符(如 RFC 822 中定义的)或验证邮件交换(mail exchange,MX)记录,但这些功能不属于 JavaMail API。
[JavaMail]6 常见问题
1、javamail在tomcat中找不到类库。
Javamail中tomcat中使用,报java.lang.NoClassDefFoundError: javax/mail/MessagingException的错误。找不到javamail的类库。把javamail类库文件activation.jar 以及 mail.jar 放到TOMCAT_HOME/common/lib下,应该就搞定了!
[JavaMail]7 详解Address和RFC 822
A、名称解释
  电子邮件的标准格式 (RFC 822)
  除了由一个Internet用户传递给另一个用户的信息之外,电子邮件中还必须包含附加的服务信息。SMTP服务器利用这些信息来传递邮件,而客户端的邮件接收软件则利用这些信息来对邮件进行分类。
  每封邮件都有两个部分:信头和主体。
  信头部分的字段可分为两类。一类是由你的电子邮件程序产生的,另一类是邮件通过SMTP服务器时被加上的。在所有被SMTP服务器加上的字段中,对我们而言最重要的是Message-Id字段。这个字段是由你传向的SMTP服务器加上的。这是一个唯一的ID号。你可用这个号码作为邮件的编号。
  下表列出了可由用户的邮件程序控制的信头字段。这并不意味着所有的字段都是必须的。实际上可以忽略形成信头这一步骤而只发送正文。让你的SMTP服务器为你加上最起码的必需字段。
  信头字段 目的
  From 邮件作者
  Sender 发信人
  Reply-To 回邮地址
  To 收信人地址
  CC 抄送:另一个收信人地址
  BCC 密送:收信人地址,但其它收信人看不到这个收信人的地址。
  Subject 主题
  Comments 备注
  Keywords 关键字,用来进一步搜索邮件
  In-Reply-To 被当前邮件回复的邮件的ID
  References 几乎同In-Reply-To一样
  Encrypted 加密邮件的加密类型
  Date 发信日期
B、Address
Javamail中关于Address的类共有3个类。分别是:
Javax.mail.Address (抽象基础类)
javax.mail.internet.InternetAddress (继承于Address)
javax.mail.internet.NewsAddress
B.1、Javax.mail.Address
abstract String getType()
Return a type string that identifies this address type.
返回Address的类型。若InternetAddress则返回rfc822。
abstract String toString()
Return a String representation of this address object.
返回表述Address对象的String。
B.2、javax.mail.internet.InternetAddress
这个类表示一个使用RFC822(电子邮件的标准格式)的Internet电子邮件地址。标准的地址的语法格式为personal name&user@host.domain&。
String address
String encodedPersonal
The RFC 2047 encoded version of the personal name.
String personal
String toString()
Convert this address into a RFC 822 / RFC 2047 encoded address.
把Address转换成一个RFC822/ RFC2047编码的String。
String toUnicodeString()
Returns a properly formatted address (RFC 822 syntax) of Unicode characters.
返回一个Unicode字符格式的地址(RFC822语法)。
static String toString(Address[] addresses)
Convert the given array of InternetAddress objects into a comma separated sequence of address strings. The resulting string contains only US-ASCII characters, and hence is mail-safe.把一个InternetAddress 数组转换成一个由逗号分隔的地址字符串String(符合RFC822/ RFC2047)。这个String只能包含US_ASCII码。
static String toString(Address[] addresses, int used)
Convert the given array of InternetAddress objects into a comma separated sequence of address strings. The resulting string contains only US-ASCII characters, and hence is mail-safe.
The 'used' parameter specifies the number of character positions already taken up in the field into which the resulting address sequence string is to be inserted. It is used to determine the line-break positions in the resulting address sequence string.
used参数用于指定要被插入字符串的字符位置数。
static InternetAddress[] parse(String addresslist)
Parse the given comma separated sequence of addresses into InternetAddress objects.
把一个由逗号分隔的地址字符串系列解析成InternetAddress数组。地址必须遵循RFC822中的语法。
static InternetAddress[] parse(String addresslist, boolean strict)
Parse the given sequence of addresses into InternetAddress objects. If strict is false, simple email addresses separated by spaces are also allowed. If strict is true, many (but not all) of the RFC822 syntax rules are enforced. In particular, even if strict is true, addresses composed of simple names (with no &@domain& part) are allowed. Such &illegal& addresses are not uncommon in real messages.
把一个地址字符串系列解析成InternetAddress数组。若strict是false,由空格分隔的简单邮件地址也是允许的。若strict是true,许多(但不是全部)RFC822语法规则将被执行。即使strict是true,若地址不包含(@域名)部分也是允许的。
没有strict参数的通常用于解析用户输入的邮件地址字符串
static InternetAddress[] parseHeader(String addresslist, boolean strict)
Parse the given sequence of addresses into InternetAddress objects.
把一个地址字符串系列解析成InternetAddress数组。若strict是false,个人地址的完整语法规则都不用执行。若strict是true,许多(但不是全部)RFC822语法规则将被执行。
为了更好的支持消息中的无效地址。若strict是false,此方法执行比parse(“xx”,false)还要少的语法规则。若strict是true,此方法执行比parse(“xx”,true)更多的语法规则。
3.获取当前用户地址
static InternetAddress
getLocalAddress(Session session)
Return an InternetAddress object representing the current user.
[JavaMail]8 详解Message和MIME
Multipurpose Internet Mail Extension(多功能Internet 邮件扩充服务)
它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。服务器会将它们发送的多媒体数据的类型告诉浏览器,而通知手段就是说明该多媒体数据的MIME类型,从而让浏览器知道接收到的信息哪些是MP3文件,哪些是Shockwave文件等等。服务器将MIME标志符放入传送的数据中来告诉浏览器使用哪种插件读取相关文件。
MIME能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。这个标准被定义在; RFC 2045,; RFC 2046,; RFC 2047,; RFC 2048,; RFC 2049等RFC中。 由RFC 822转变而来的RFC 2822,规定电子邮件标准并不允许在邮件消息中使用7位ASCII字符集以外的字符。正因如此,一些非英语字符消息和二进制文件,图像,声音等非文字消息都不能在电子邮件中传输。MIME规定了用于表示各种各样的数据类型的符号化方法。
MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。
由于MIME类型与文档的后缀相关,因此服务器使用文档的后缀来区分不同文件的MIME类型,服务器中必须定义文档后缀和MIME类型之间的对应关系。而客户程序从服务器上接收数据的时候,它只是从服务器接受数据流,并不了解文档的名字,因此服务器必须使用附加信息来告诉客户程序数据的MIME类型。服务器在发送真正的数据之前,就要先发送标志数据的MIME类型的信息,这个信息使用Content-type关键字进行定义,例如对于HTML文档,服务器将首先发送以下(Content-type: text/html)MIME标识信息,这个标识并不是真正的数据文件的一部分。
MIME利用了一个事实就是,RFC 822在消息体的内容中做了一点限制:唯一的限制就是只能使用简单的ASCII文本。所以,MIME信息由正常的Internet文本邮件组成,文本邮件拥有一些特别的符合RFC 822的信息头和格式化过的信息体(用ASCII 的子集来表示的附件)。这些MIME头给出了一种在邮件中表示附件的特别的方法。
A.1、MIME信息的剖析
  一个普通的文本邮件的信息包含一个头部分(To: From: Subject: 等等)和一个体部分(Hello Mr.,等等)。邮件的各个部分叫做MIME段,每段前也缀以一个特别的头。MIME邮件只是基于RFC 822邮件的一个扩展,然而它有着自己的RFC规范集。
  MIME头根据在邮件包中的位置,大体上分为MIME信息头和MIME段头。(译者:MIME信息头指整个邮件的头,而MIME段头只每个MIME段的头。)
MIME信息头
  0.MIME-Version:
  这个头提供了所用MIME的版本号。这个值习惯上为1.0。
  1.Content-Type:
它定义了数据的类型,以便数据能被适当的处理。有效的类型有:text,image,audio,video, applications,multipart和message。注意任何一个二进制附件都应该被叫做application/octet- stream。这个头的一些用例为:image/jpg, application/mswork,multipart/mixed,这只是很少的一部分。
2.Content-ID:
  如果Content-Type是message/external-body或multipart/alternative时,这个头就有用了,它超出了本文的范围。
3.Content-MD5
4.Content- Language
5.Content-Description:
  这是一个可选的头。它是任何信息段内容的自由文本描述。描述必须使用us-ascii码。
  6.Content-Disposition:
一个试验性的头,它用于给客户程序/MUA提供提示,来决定是否在行内显示附件或作为单独的附件。
  7.Content-Transfer-Encoding:
这是所有头中最重要的一个,因为它说明了对数据所执行的编码方式,客户/MUA 将用它对附件进行解码。对于每个附件,可以使用7bit,8bit,binary ,quoted-printable,base64和x-encodingname中的一种编码方式。
7bit这里指的是7位的ASCII编码方式。编码是用在US ASCII字符集上的常用的一种编码方式,也就是,保持它的原样。
8位元ASCII码。
binary编码一般不用。
quoted printable
因为欧洲的一些文字和ASCII字符集中的某些字符有部分相同。如果邮件消息使用的是这些语言的话,于ASCII重叠的那些字符可以原样使用,ASCII字符集中不存在的字符采用形如“=??”的方法编码。这里“??”需要用将字符编码后的16进制数字来指定。采用quoted-printable编码的消息,长度不会变得太长,而且大部分都是ASCII中的字符,即使不通过解码也大致可以读懂消息的内容。
base64是一种将二进制的01序列转化成ASCII字符的编码方法。编码后的文本或者二进制消息,就可以运用SMTP等只支持ASCII字符的协议传送了。Base64一般被认为会平均增加33%的报文长度,而且,经过编码的消息对于人类来说是不可读的。
x-encodingname
这个值是预留的扩展。
11.Reply-To
12. To CC BCC
To 收信人地址
  CC 抄送:另一个收信人地址
BCC 密送:收信人地址,但其它收信人看不到这个收信人的地址。
13.Subject
14.Message-ID
  MIME段头(出现在实际的MIME附件部分的头),除了MIME-Version头,可以拥有以上任何头字段。如果一个MIME头是信息块的一部分,它将作用于整个信息体。例如,如果Content-Transfer-Encoding显示在信息(指整个信息)头中,它应用于整个信息体,但是如果它显示在一个MIME段里,它&只能&用于那个段中。
B、Message
javax.mail.Part (基础接口)
public interface Part
Part是Message和BodyParts的基础接口。Part一组由attribute和Content组成。
JavaMail定义了一组标准属性,大多数现有的邮件服务器都支持。这些属性都有set和get方法存取。其他非标准属性用setHeader()和getHeader()存取。
Part中的Content存在以下格式,DataHandler,input stream,Java object。
DataHandler通过getDataHandler()获取,DataHandler对象允许客户发现在content上的有效方法,然后实例化合适的组件来执行这些操作。
input stream通过getInputStream()获取,在取得input stream之前,所有邮件格式编码
已经被解析。
Java object通过getContent()获取,返回对象可能是一个多Multipart对象。
javax.mail.internet. MimePart (继承于Part)
public interface MimePart extends Part
添加对RFC822 RFC2045 MIME的支持。
javax.mail.Message (抽象基础类)
public abstract class Message implements Part
javax.mail.internet.MimeMessage (继承于Message)
public class MimeMessage extends Message implements MimePart
B.1、javax.mail.Part
isMimeType(String mimeType)
Is this Part of the specified MIME type? This method compares only the primaryType and subType.
判断Part是否是指定的MIME类型,此法方法只判断主类型和子类型。内容参数将被忽略。如:但用isMimeType(&text/plain”);比较&text/ charset=foobar&.时,将返回true。当子类型使用特殊字符”*”时,子类型的比较也将被忽略。
B.2、javax.mail.Message
Messages是一个抽象类,它实现接口Part,并定义了一些属性。Message可以从Folder取得或由MimeMessage创建。在Folder中的Message有一组flags来表明它在Folder中的状态。
True if this message has been expunged.
True表示message已经被除去。
The containing folder, if this message is obtained from a folder
若message由folder取得,则表示对应的folder。
The number of this message within its folder, or zero if the message was not retrieved from a folder.
表示message在folder中的位置,0表示message不在folder中。在文件中第一个邮件为1,依次递增。
The Session object for this Message
操作msgnum属性的方法
对应邮件中的Form:邮件作者
getMessageNumber()
setMessageNumber(int msgnum)
B.2、javax.mail.internet.MimeMessage
这个类描述了一个MIME类型的email message,它实现了MimePart接口。客户想要创建一个MIME类型的message,必须先创建一个空的MimeMessage对象,再填充属性和容器。
Byte array that holds the bytes of this Message's content.
message的容器,存储邮件正文和附件。
InputStream
contentStream
If the data for this message was supplied by an InputStream that implements the SharedInputStream interface, contentStream is another such stream representing the content of this message.
DataHandler
The DataHandler object representing this Message's content.
The Flags for this message.
邮件的标记信息,如:被看过或被删除等。
InternetHeaders headers
The InternetHeaders object that stores the header of this message.
存储message的head部分。
A flag indicating whether the message has been modified.
Does the saveChanges method need to be called on this message?
Content- Type
对应邮件头中的Content-Type:
String getContentType()
Content-ID
对应邮件头中的Content-ID:
String getContentID()
Returns the value of the &Content-ID& header field.
setContentID(String cid)
Set the &Content-ID& header field of this Message.
操作Content-ID属性的方法
Content-MD5
对应邮件头中的Content-MD5:
getContentMD5()
setContentMD5(String md5)
Content- Language
对应邮件头中的Content-Language:
getContentLanguage()
setContentLanguage(String[] languages)
Content- Description
对应邮件头中的Content- Description:
String getDescription()
Returns the &Content-Description& header field of this Message.
setDescription(String description)
Set the &Content-Description& header field for this Message.
void setDescription(String description, String charset)
Set the &Content-Description& header field for this Message.
Content- Disposition
对应邮件头中的Content- Disposition:
getDisposition()
setDisposition(String disposition)
Content- Transfer-Encoding
对应邮件头中的Content-Transfer-Encoding:
String getEncoding()
对应邮件头中的Date:发信日期
setSentDate(Date d)
Set the RFC 822 &Date& header field.
getSentDate()
Returns the value of the RFC 822 &Date& field.
操作Date属性的方法
对应邮件头中的Form:邮件作者
addFrom(Address[] addresses)
Add the specified addresses to the existing &From& field.
Address[] getFrom()
Returns the value of the RFC 822 &From& header fields.
Set the RFC 822 &From& header field using the value of the InternetAddress.getLocalAddress method.
setFrom(Address address)
Set the RFC 822 &From& header field.
操作Form属性的方法
对应邮件中的Sender:发信人
setSender(Address address)
Set the RFC 822 &Sender& header field.
Address getSender()
Returns the value of the RFC 822 &Sender& header field.
操作Sender属性的方法
From和Sender
合法的信件头部必须包括 &From:& 行
合法的信件头部也许会包括 &Sender:& 行
如果信件即包括 &From:& 又包括 &Sender:&,那么 &Sender:& 是发送者
如果信件包括 &From:& 但不包括 &Sender:&,那么 &From:& 里面的第一个地址是发送者
如果信件不包括 &From:&,那么这封信肯定不可能是 DomainKey 签名过的(包括有 &Sender:& 而无 &From:& 的情况)
对应邮件中的Reply-To:回邮地址
set ReplyTo (Address address)
Address get ReplyTo ()
操作Reply-To属性的方法
对应邮件中的To:CC:BCC:
addRecipients(Message.RecipientType type, Address[] addresses)
Add the given addresses to the specified recipient type.
addRecipients(Message.RecipientType type, String addresses)
Add the given addresses to the specified recipient type.
Address[] getAllRecipients()
Get all the recipient addresses for the message.
Address[] getRecipients(Message.RecipientType type)
Returns the recepients specified by the type.
操作收件人属性的方法
对应邮件头中的Subject:主题
setSubject(String subject)
Set the &Subject& header field.
setSubject(String subject, String charset)
Set the &Subject& header field.
String getSubject()
Returns the value of the &Subject& header field.
操作Subject属性的方法
ncoded-word = &=?& charset &?& encoding &?& encoded-text &?=&
charset:字符编码
encoding:
Q --- Quote Printable
B --- BASE64
U --- UUENCODE
例1: Subject: =?GB2312?Q?=C4=E3=BA=C3?=
例2: Subject: =?utf-7?B?WFgrWUNkU0swNE9kbjVPRVZiKy0z?=
Message-ID
对应邮件头中的Message-ID:SMTP服务器加的唯一的ID号。可用这个号码作为邮件的编号。
String getMessageID()
Returns the value of the &Message-ID& header field.
取得Message-ID属性的方法
操作Head的方法
getHeader(String name)
Get all the headers for this header_name.
获取指定名称的所有header。请注意,某些标题如果它们包含非US-ASCII字符则可能被编码为RFC 2047,这些应该被解码。
getHeader(String name, String delimiter)
Get all the headers for this header name, returned as a single String, with headers separated by the delimiter.
获取指定名称的所有header。返回一个由指定delimiter分隔的单一字符串。若delimiter是null,则只有第一个header被返回。
Enumeration
getAllHeaderLines()
Get all header lines as an Enumeration of Strings.
Enumeration
getAllHeaders()
Return all the headers from this Message as an enumeration of Header objects.
Enumeration
getMatchingHeaderLines(String[] names)
Get matching header lines as an Enumeration of Strings.
Enumeration
getMatchingHeaders(String[] names)
Return matching headers from this Message as an Enumeration of Header objects.
Enumeration
getNonMatchingHeaderLines(String[] names)
Get non-matching header lines as an Enumeration of Strings.
Enumeration
getNonMatchingHeaders(String[] names)
Return non-matching headers from this Message as an Enumeration of Header objects.
setHeader(String name, String value)
Set the value for this header_name.
addHeader(String name, String value)
Add this value to the existing values for this header_name.
addHeaderLine(String line)
Add a raw RFC 822 header-line.
removeHeader(String name)
Remove all headers with this name.
取得邮件收到的时间
对应邮件头中第一行
getReceivedDate()
Returns the Date on this message was received.
操作邮件标记Flag的方法
getFlags()
Return a Flags object containing the flags for this message.
setFlags(Flags flag, boolean set)
Set the flags for this message.
isSet(Flags.Flag flag)
Check whether the flag specified in the flag argument is set in this message.
取得邮件大小
Return the size of the content of this message in bytes.
Message reply(boolean replyToAll)
Get a new Message suitable for a reply to this message.
返回一个Message用于回复这个邮件的。
getFileName()
Get the filename associated with this Message.
setFileName(String filename)
Set the filename associated with this part, if possible.
getLineCount()
Return the number of lines for the content of this message.
saveChanges()
Updates the appropriate header fields of this message to be consistent with the message's contents.
操作Java Object类型的Content的方法
getContent()
Return the content as a Java object.
InputStream
getInputStream()
Return a decoded input stream for this Message's &content&.
setContent(Multipart mp)
This method sets the Message's content to a Multipart object.
setContent(Object o, String type)
A convenience method for setting this Message's content.
setText(String text)
Convenience method that sets the given String as this part's content, with a MIME type of &text/plain&.
setText(String text, String charset)
Convenience method that sets the given String as this part's content, with a MIME type of &text/plain& and the specified charset.
setText(String text, String charset, String subtype)
Convenience method that sets the given String as this part's content, with a primary MIME type of &text& and the specified MIME subtype.
操作DataHandler类型的Content的方法
DataHandler
getDataHandler()
Return a DataHandler for this Message's content.
setDataHandler(DataHandler dh)
This method provides the mechanism to set this part's content.
操作Input Stream类型的Content的方法
InputStream getRawInputStream()
Return an InputStream to the raw data with any Content-Transfer-Encoding intact.
parse(InputStream is)
Parse the InputStream setting the headers and content fields appropriately.
输出attribute和content安全字节流
writeTo(OutputStream os)
Output the message as an RFC 822 format stream.
writeTo(OutputStream os, String[] ignoreList)
Output the message as an RFC 822 format stream, without specified headers.
C.1、常见的MIME类型
  超文本标记语言文本 .html text/html
  xml文档 .xml text/xml
  XHTML文档 .xhtml application/xhtml+xml
  普通文本 .txt text/plain
  RTF文本 .rtf application/rtf
  PDF文档 .pdf application/pdf
  Microsoft Word文件 .word application/msword
  PNG图像 .png image/png
  GIF图形 .gif image/gif
  JPEG图形 .jpeg,.jpg image/jpeg
  au声音文件 .au audio/basic
  MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
  RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
  MPEG文件 .mpg,.mpeg video/mpeg
  AVI文件 .avi video/x-msvideo
  GZIP文件 .gz application/x-gzip
  TAR文件 .tar application/x-tar
任意的二进制数据 application/octet-stream
C.2、MIME类型大全
格式前面为后辍名,后面为对应的MIME型(例如:rar application/x-rar-compressed 表示.RAR对应的是application/x-rar-compressed )
  application/vnd.lotus-1-2-3
  3gp video/3gpp
  aab application/x-authoware-bin
  aam application/x-authoware-map
  aas application/x-authoware-seg
  ai application/postscript
  aif audio/x-aiff
  aifc audio/x-aiff
  aiff audio/x-aiff
  als audio/X-Alpha5
  amc application/x-mpeg
  ani application/octet-stream
  asc text/plain
  asd application/astound
  asf video/x-ms-asf
  asn application/astound
  asp application/x-asap
  asx video/x-ms-asf
  au audio/basic
  avb application/octet-stream
  avi video/x-msvideo
  awb audio/amr-wb
  bcpio application/x-bcpio
  bin application/octet-stream
  bld application/bld
  bld2 application/bld2
  bmp application/x-MS-bmp
  bpk application/octet-stream
  bz2 application/x-bzip2
  cal image/x-cals
  ccn application/x-cnc
  cco application/x-cocoa
  cdf application/x-netcdf
  cgi magnus-internal/cgi
  chat application/x-chat
  class application/octet-stream
  clp application/x-msclip
  cmx application/x-cmx
  co application/x-cult3d-object
  cod image/cis-cod
  cpio application/x-cpio
  cpt application/mac-compactpro
  crd application/x-mscardfile
  csh application/x-csh
  csm chemical/x-csml
  csml chemical/x-csml
  css text/css
  cur application/octet-stream
  dcm x-lml/x-evm
  dcr application/x-director
  dcx image/x-dcx
  dhtml text/html
  dir application/x-director
  dll application/octet-stream
  dmg application/octet-stream
  dms application/octet-stream
  doc application/msword
  dot application/x-dot
  dvi application/x-dvi
  dwf drawing/x-dwf
  dwg application/x-autocad
  dxf application/x-autocad
  dxr application/x-director
  ebk application/x-expandedbook
  emb chemical/x-embl-dl-nucleotide
  embl chemical/x-embl-dl-nucleotide
  eps application/postscript
  epub application/epub+zip
  eri image/x-eri
  es audio/echospeech
  esl audio/echospeech
  etc application/x-earthtime
  etx text/x-setext
  evm x-lml/x-evm
  evy application/x-envoy
  exe application/octet-stream
  fh4 image/x-freehand
  fh5 image/x-freehand
  fhc image/x-freehand
  fif image/fif
  fm application/x-maker
  fpx image/x-fpx
  fvi video/isivideo
  gau chemical/x-gaussian-input
  gca application/x-gca-compressed
  gdb x-lml/x-gdb
  gif image/gif
  gps application/x-gps
  gtar application/x-gtar
  gz application/x-gzip
  hdf application/x-hdf
  hdm text/x-hdml
  hdml text/x-hdml
  hlp application/winhlp
  hqx application/mac-binhex40
  htm text/html
  html text/html
  hts text/html
  ice x-conference/x-cooltalk
  ico application/octet-stream
  ief image/ief
  ifm image/gif
  ifs image/ifs
  imy audio/melody
  ins application/x-NET-Install
  ips application/x-ipscript
  ipx application/x-ipix
  it audio/x-mod
  itz audio/x-mod
  ivr i-world/i-vrml
  j2k image/j2k
  jad text/vnd.sun.j2me.app-descriptor
  jam application/x-jam
  jar application/java-archive
  jnlp application/x-java-jnlp-file
  jpe image/jpeg
  jpeg image/jpeg
  jpg image/jpeg
  jpz image/jpeg
  js application/x-javascript
  jwc application/jwc
  kjx application/x-kjx
  lak x-lml/x-lak
  latex application/x-latex
  lcc application/fastman
  lcl application/x-digitalloca
  lcr application/x-digitalloca
  lgh application/lgh
  lha application/octet-stream
  lml x-lml/x-lml
  lmlpack x-lml/x-lmlpack
  lsf video/x-ms-asf
  lsx video/x-ms-asf
  lzh application/x-lzh
  m13 application/x-msmediaview
  m14 application/x-msmediaview
  m15 audio/x-mod
  m3u audio/x-mpegurl
  m3url audio/x-mpegurl
  ma1 audio/ma1
  ma2 audio/ma2
  ma3 audio/ma3
  ma5 audio/ma5
  man application/x-troff-man
  map magnus-internal/imagemap
  mbd application/mbedlet
  mct application/x-mascot
  mdb application/x-msaccess
  mdz audio/x-mod
  me application/x-troff-me
  mel text/x-vmel
  mi application/x-mif
  mid audio/midi
  midi audio/midi
  mif application/x-mif
  mil image/x-cals
  mio audio/x-mio
  mmf application/x-skt-lbs
  mng video/x-mng
  mny application/x-msmoney
  moc application/x-mocha
  mocha application/x-mocha
  mod audio/x-mod
  mof application/x-yumekara
  mol chemical/x-mdl-molfile
  mop chemical/x-mopac-input
  mov video/quicktime
  movie video/x-sgi-movie
  mp2 audio/x-mpeg
  mp3 audio/x-mpeg
  mp4 video/mp4
  mpc application/vnd.mpohun.certificate
  mpe video/mpeg
  mpeg video/mpeg
  mpg video/mpeg
  mpg4 video/mp4
  mpga audio/mpeg
  mpn application/vnd.mophun.application
  mpp application/vnd.ms-project
  mps application/x-mapserver
  mrl text/x-mrml
  mrm application/x-mrm
  ms application/x-troff-ms
  mts application/metastream
  mtx application/metastream
  mtz application/metastream
  mzv application/metastream
  nar application/zip
  nbmp image/nbmp
  nc application/x-netcdf
  ndb x-lml/x-ndb
  ndwn application/ndwn
  nif application/x-nif
  nmz application/x-scream
  nokia-op-logo image/vnd.nok-oplogo-color
  npx application/x-netfpx
  nsnd audio/nsnd
  nva application/x-neva1
  oda application/oda
  oom application/x-AtlasMate-Plugin
  pac audio/x-pac
  pae audio/x-epac
  pan application/x-pan
  pbm image/x-portable-bitmap
  pcx image/x-pcx
  pda image/x-pda
  pdb chemical/x-pdb
  pdf application/pdf
  pfr application/font-tdpfr
  pgm image/x-portable-graymap
  pict image/x-pict
  pm application/x-perl
  pmd application/x-pmd
  png image/png
  pnm image/x-portable-anymap
  pnz image/png
  pot application/vnd.ms-powerpoint
  ppm image/x-portable-pixmap
  pps application/vnd.ms-powerpoint
  ppt application/vnd.ms-powerpoint
  pqf application/x-cprplayer
  pqi application/cprplayer
  prc application/x-prc
  proxy application/x-ns-proxy-autoconfig
  ps application/postscript
  ptlk application/listenup
  pub application/x-mspublisher
  pvx video/x-pv-pvx
  qcp audio/vnd.qcelp
  qt video/quicktime
  qti image/x-quicktime
  qtif image/x-quicktime
  r3t text/vnd.rn-realtext3d
  ra audio/x-pn-realaudio
  ram audio/x-pn-realaudio
  rar application/octet-stream
  ras image/x-cmu-raster
  rdf application/rdf+xml
  rf image/vnd.rn-realflash
  rgb image/x-rgb
  rlf application/x-richlink
  rm audio/x-pn-realaudio
  rmf audio/x-rmf
  rmm audio/x-pn-realaudio
  rmvb audio/x-pn-realaudio
  rnx application/vnd.rn-realplayer
  roff application/x-troff
  rp image/vnd.rn-realpix
  rpm audio/x-pn-realaudio-plugin
  rt text/vnd.rn-realtext
  rte x-lml/x-gps
  rtf application/rtf
  rtg application/metastream
  rtx text/richtext
  rv video/vnd.rn-realvideo
  rwc application/x-rogerwilco
  s3m audio/x-mod
  s3z audio/x-mod
  sca application/x-supercard
  scd application/x-msschedule
  sdf application/e-score
  sea application/x-stuffit
  sgm text/x-sgml
  sgml text/x-sgml
  sh application/x-sh
  shar application/x-shar
  shtml magnus-internal/parsed-html
  shw application/presentations
  si6 image/si6
  si7 image/vnd.stiwap.sis
  si9 image/vnd.lgtwap.sis
  sis application/vnd.symbian.install
  sit application/x-stuffit
  skd application/x-Koan
  skm application/x-Koan
  skp application/x-Koan
  skt application/x-Koan
  slc application/x-salsa
  smd audio/x-smd
  smi application/smil
  smil application/smil
  smp application/studiom
  smz audio/x-smd
  snd audio/basic
  spc text/x-speech
  spl application/futuresplash
  spr application/x-sprite
  sprite application/x-sprite
  sdp application/sdp
  spt application/x-spt
  src application/x-wais-source
  stk application/hyperstudio
  stm audio/x-mod
  sv4cpio application/x-sv4cpio
  sv4crc application/x-sv4crc
  svf image/vnd
  svg image/svg-xml
  svh image/svh
  svr x-world/x-svr
  swf application/x-shockwave-flash
  swfl application/x-shockwave-flash
  t application/x-troff
  tad application/octet-stream
  talk text/x-speech
  tar application/x-tar
  taz application/x-tar
  tbp application/x-timbuktu
  tbt application/x-timbuktu
  tcl application/x-tcl
  tex application/x-tex
  texi application/x-texinfo
  texinfo application/x-texinfo
  tgz application/x-tar
  thm application/vnd.eri.thm
  tif image/tiff
  tiff image/tiff
  tki application/x-tkined
  tkined application/x-tkined
  toc application/toc
  toy image/toy
  tr application/x-troff
  trk x-lml/x-gps
  trm application/x-msterminal
  tsi audio/tsplayer
  tsp application/dsptype
  tsv text/tab-separated-values
  ttf application/octet-stream
  ttz application/t-time
  txt text/plain
  ult audio/x-mo

我要回帖

更多关于 表格打印出现上百页 的文章

 

随机推荐