JavaMail

建立JavaMail使用环境,需要哪些软件 

首先,需要安装JavaMail API。现在有两种常用的 JavaMail API 版本:1.2 和 1.1.3。虽然版本 1.2 是最新版,但版本 1.1.3 包含了Java 2 平台企业版(Java 2 Platform, Enterprise Edition,J2EE)的版本 1.2.1,所以仍然有很多人使用它。
  ·JavaMail 1.2 的安装
  要使用 JavaMail 1.2 API,请下载 JavaMail 1.2 实现,解开Javamail-1_2.zip 文件,并将 mail.jar 文件添加到 CLASSPATH 中;除了核心类,随版本 1.2 实现一起提供的还有 SMTP、IMAP4 和 POP3 供应商。另外,应该将 activation.jar 文件添加到 CLASSPATH 中了。


Java Mail API有哪些核心类 

  ·Javax.mail.Session:Session 类定义了一个基本邮件会话(session),是Java Mail API最高层入口类。所有其它类都是经由这个session 才得以生效。Session 对象用 Java.util.Properties 对象获取信息,如邮件服务器、用户名、密码及整个应用程序中共享的其它信息。


  ·Javax.mail.Message:一旦获得 Session 对象,就可以继续创建要发送的消息。这由 Message 类来完成。因为 Message 是个抽象类,必需用一个子类,多数情况下为 Javax.mail.internet.MimeMessage。MimeMessage 是个能理解 MIME 类型和头的电子邮件消息,正如不同 RFC 中所定义的。虽然在某些头部域非 ASCII 字符也能被译码,但 Message 头只能被限制为用 US-ASCII 字符。


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


  ·Javax.mail. Authenticator:与Java.net中同名的Authenticator类一样,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 对象返回给调用程序。


  ·Javax.mail.Transport:消息发送的最后一部分是使用 Transport 类。这个类用协议指定的语言发送消息(通常是 SMTP)。它是抽象类,它的工作方式与 Session 有些类似。仅调用静态 send() 方法,就能使用类的 缺省 版本:Transport.send(message);或者,读者也可以从针对自己的协议的会话中获得一个特定的实例,传递用户名和密码(如果不必要就不传),发送消息,然后关闭连接。 


  ·Javax.mail.Store:Store类实现特定邮件协议上的读、写、监视、查找等操作。通过Javax.mail.Store类可以访问Javax.mail.Folder类。


  ·Javax.mail.Folder:Folder类用于分级组织邮件,并提供照Javax.mail.Message格式访问email的能力。

代码举例:

Properties props = new Properties();
Session sendMailSession;
Store store;
Transport transport; 

sendMailSession = Session.getInstance(props, null);
props.put("mail.smtp.host", "smtp.jspinsider.com");
Message newMessage = new MimeMessage(sendMailSession);
newMessage.setFrom(new InternetAddress("fromuser@qq.com"));
newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress ("touser@qq.com"));
newMessage.setSubject("subject");
newMessage.setSentDate(new Date());
newMessage.setText(“textcontent”);
transport = sendMailSession.getTransport("smtp");
transport.send(newMessage);


如何发送HTML类型的邮件 
在上面的例子中,我们实现了如何发送文本格式的邮件,那么HTML格式的邮件该如何发送呢?那就看看下面的例子吧。

String smtp;//SMTP主机

String from;//发信人

String to;//收信人

String cc;//抄送人

String bcc;//暗送人

String subject;//主题

String body; //内容

if(subject!=null){
subject = new Java.lang.String(subject.getBytes("iso-8859-1"));
}
//发送邮件
HTML.send(smtp,from,to,cc,bcc,subject,body);

-----------------------------------------------------------------------------------

public final class HTML {
public static void send(
String smtp,   /*SMTP主机地址*/
String from,   /*发信人*/
String to,   /*收信人*/
String cc,   /*抄送人*/
String bcc,  /*暗送人*/
String subject, /*主题*/
String body /*内容*/
    ) throws Java.lang.Exception {
    //变量声明
Java.util.Properties props; //系统属性
    Javax.mail.Session mailSession; //邮件会话对象
     Javax.mail.internet.MimeMessage mimeMsg;//MIME邮件对象 

    //设置系统属性
props = Java.lang.System.getProperties();//获得系统属性对象
    props.put("mail.smtp.host",smtp);//设置SMTP主机 


    //获得邮件会话对象
   mailSession = Javax.mail.Session.getDefaultInstance(props,null); 

    //创建MIME邮件对象
    mimeMsg = new Javax.mail.internet.MimeMessage(mailSession); 

   //设置发信人
    mimeMsg.setFrom(new Javax.mail.internet.InternetAddress(from)); 

    //设置收信人
    if(to!=null){ 
mimeMsg.setRecipients(Javax.mail.Message.RecipientType.TO,Javax.mail. internet.InternetAddress.parse(to));
   

    //设置抄送人
    if(cc!=null){
mimeMsg.setRecipients(Javax.mail.Message.RecipientType.CC,Javax.mail. internet.InternetAddress.parse(cc));
   

//设置暗送人
if(bcc!=null){ 
mimeMsg.setRecipients(Javax.mail.Message.RecipientType.BCC,Javax.mail. internet.InternetAddress.parse(bcc));
    

    //设置邮件主题
   //mimeMsg.setSubject(subject);
    mimeMsg.setSubject(subject,"gb2312"); 

     //设置邮件内容,将邮件body部分转化为HTML格式
    mimeMsg.setDataHandler(new Javax.activation.DataHandler(new StringDataSource(body,"text/html"))); 

    //发送邮件
   Javax.mail.Transport.send(mimeMsg);
  }
}


public class StringDataSource implements Javax.activation.DataSource {
private String data;
   private String type; 

  public StringDataSource(Java.lang.String data,Java.lang.String type){
     this.data = data;
   this.type = type;
  

  public Java.io.InputStream getInputStream() throws Java.io.IOException{
    return new Java.io.StringBufferInputStream(data);


   public Java.io.OutputStream getOutputStream() throws Java.io.IOException{
    throw new Java.io.IOException("it does not support this method now!");
 

  public Java.lang.String getContentType(){
     return type;


   public Java.lang.String getName(){
       return " mymail ";
}
}


如何实现消息和标志的删除?


消息的删除涉及到与消息相关的 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提出请求。
要删除消息,您可以设置消息的DELETED标志:
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()检查。 


如何实现消息的转发?

转发消息,相对于其他功能来说,显得有些棘手。没有单独的方法可以供调用,读者必须通过对组成消息各部分的处理来组织要转发的消息。
一条邮件消息可以由多个部分组成。在处理MIME消息时,消息中每部分都是BodyPart(MimeBodyPart)。不同的body part(信体部件或正文部件)结合成一个容器,名为Multipart(MimeMultipart)。要转发一条消息,您为自己的消息正文创建一个部件,要转发的消息作为另一部件。并且将两个部件结合成一个Multipart(多部件)。然后您将这个Multipart添加到一则已写好恰当地址的消息中,并发送。
要将一条消息内容复制到另一条,只要复制 DataHandler(JavaBeans Activation Framework中的类)就行了。 

// Create the message to forward
Message forward = new MimeMessage(session);

// Fill in header
forward.setSubject("Fwd: " + message.getSubject());
forward.setFrom(new InternetAddress(from));
forward.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

// Create your new message part
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText( "Here you go with the original message:\n\n");

// Create a multi-part to combine the parts
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart); 

// Create and fill part for the forwarded content
messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(message.getDataHandler()); 

// Add part to multi part
multipart.addBodyPart(messageBodyPart); 

// Associate multi-part with message
forward.setContent(multipart); 

// Send message
Transport.send(forward);


怎样处理附件? 


附件是邮件消息的相关资源,如通常不包含在消息正文里文本文件、电子表格或图像等。常见的邮件程序,可以用JavaMail API将资源attach(附加)到您的消息上,就可以在收到消息时得到。

附件的发送:
发送附件非常像转发消息。您建立各部分以组成完整消息。完成第一部件,即消息正文后,您添加其它部件,其中每个DataHandler都代表附件,而不是转发消息情况下的共享处理程序。如果从文件中读附件,附件的数据源是FileDataSource。而如果从URL中读时,附件的数据源是URLDataSource。一旦存在DataSource,只要先把它传递给 DataHandler 构造器,最后再用 setDataHandler() 把它附加到 BodyPart。假定您要保留附件的原始文件名,最终要做的是用BodyPart的setFileName()方法设置与附件相关的文件名。如下所示: 

// Define message
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
  new InternetAddress(to));
message.setSubject("Hello JavaMail Attachment"); 

// Create the message part
BodyPart messageBodyPart = new MimeBodyPart(); 

// Fill the message
messageBodyPart.setText("Pardon Ideas"); 

Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart); 

// Part two is attachment
messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart); 

// Put parts in message
message.setContent(multipart); 

// Send the message
Transport.send(message);

注意:消息大小由SMTP服务器而不是 JavaMail API 来限制。如果您碰到问题,可以考虑用设置ms和mx参数的方法增大 ava堆大小。 

附件的获取: 

从消息中获取附件比发送它们棘手些,因为MIME没有简单的关于附件的概念。当消息包含附件时,消息的内容是个Multipart对象。接着,您需要处理每个Part,获取主要内容和附件。标有从 part.getDisposition() 获得的Part.ATTACHMENT配置(disposition)的部件(Part)无疑就是附件。但是,没有配置(以及一个非文本MIME类型)和带Part.INLINE配置的部件也可能是附件。当配置要么是Part.ATTACHMENT,要么是 Part.INLINE 时,这个消息部件的内容就能被保存。只要用getFileName()和getInputStream()就能分别得到原始文件名和输入流。 

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());
 }
}

saveFile() 方法仅依据文件名创建了一个 File,它从输入流中将字节读出,然后写入到文件中。万一文件已经存在,就在文件名后添加一个数字作为新文件名,如果这个文件名仍存在,则继续添,直到找不到这样的文件名为止。 
// from saveFile()
File file = new File(filename);
for (int i=0; file.exists(); i++) {
file = new File(filename+i);
}

上面的代码涵盖了最简单的情况 - 消息中各部件恰当的标记了。要涵盖所有情况,还要在配置为空时进行处理,并且获取部件的MIME类型来进行相应处理。 

if (disposition == null) {
 // Check if plain
 MimeBodyPart mbp = (MimeBodyPart)part;
 if (mbp.isMimeType("text/plain")) {
  // Handle plain
 } else {
  // Special non-attachment cases here of image/gif, text/html, ...
 }
...
}


如何一次发送多个邮件? 


取得必要的Transport对象并调用SendMessage()发送每一个邮件。注意在调用之间设置或改变接收者。

Message message = …;
Transport t = session.getTransport("smtp");
t.connect();
message.setRecipient(Message.RecipientType.TO,recipient1);
t.sendMessage(message,recipient);
message.setRecipient(Message.RecipientType.TO,recipient2);
t.sendMessage(message,recipient);
message.setRecipient(Message.RecipientType.TO,recipient3);
t.sendMessage(message,recipient);
t.close();


如何保存邮件? 

用MimeMessage类的writeTo()实例方法可以实现。用Message类的对象不能实现。

FileOutputStream fos = new FileOutputStream("test.mail");
mimemessage.writeTo(fos);


如何设置∕获取邮件的优先级? 

设置邮件的优先级,只需在消息头中添加"X-Priority"属性:

MimeMessage msg;
msg.addHeader("X-Priority","1");
同样道理,要获取邮件的优先级只要获取"X-Priority"属性的值就可以了:
String priority = msg.getHeader("X-Priority"); 


附录:Java Mail API的基本概念 

什么是Java Mail API 
JavaMail API是一个用于阅读、编写和发送电子邮件的可选包(标准扩展)。与 Eudora、pine 及 Microsoft Outlook 相似,这个包用来创建邮件用户代理(Mail User Agent,MUA) 类型程序。API的主要用途并不在于传输、发送和转发消息;这一功能范围属于某些应用程序,如sendmail及其它邮件传输代理(Mail Transfer Agent,MTA)类型程序。MUA类型的程序能让用户阅读和书写邮件,而它却依赖MTA处理实际发送。 

什么是SMTP 
SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议,它定义了发送电子邮件的机制。在 JavaMail API 环境中,基于 JavaMail 的程序将和您的公司或因特网服务供应商的(Internet Service Provider's,ISP's)SMTP 服务器通信。SMTP 服务器可将消息中转至接收方 SMTP 服务器,以便最终让用户经由 POP 或 IMAP 获得。这不是要求 SMTP 服务器成为开放的中继,尽管 SMTP 服务器支持身份验证,不过还是得确保它的配置正确。像配置服务器来中继消息或添加删除邮件账号这类任务的实现,JavaMail API中并不支持。 

什么是POP 
POP(Post Office Protocol),即邮局协议。目前用的是版本3,所以人们通常将它称为 POP3,RFC 1939 定义了这个协议。POP 和SMTP一样,也是一种机制,Internet上大多数人通过它得到邮件。该协议规定每个用户只能有一个邮箱的支持。这就是它所能做的,而这也造成了许多混淆。使用 POP 时,用户熟悉的许多性能并不是由 POP 协议支持的,如查看有几封新邮件消息这一性能。这些性能内建于如 Eudora 或 Microsoft Outlook 之类的程序中,它们能记住一些事,诸如最近一次收到的邮件,还能计算出有多少是新的。所以当使用 JavaMail API 时,如果读者想要这类信息,就只能由自己来计算了。 

什么是IMAP 
IMAP(Internet Message Access Protocol),即Internet消息访问协议,是更高级的用于接收消息的协议,在 RFC 2060 中有它的定义。目前使用的IMAP版本为4,人们习惯将它称为 IMAP4。在用到 IMAP 时,邮件服务器必需支持这个协议。不能仅仅把使用 POP 的程序用于 IMAP,并指望它支持 IMAP 所有性能。假设邮件服务器支持 IMAP,基于 JavaMail 的程序可以利用这种情况--用户在服务器上可以有多个文件夹(folder),并且这些文件夹可以被多个用户共享。因为有这一更高级的性能,您也许会认为所有用户都会使用 IMAP。事实并不是这样。要求服务器接收新消息,在用户请求时发送到用户手中,还要在每个用户的多个文件夹中维护消息。这样虽然能将消息集中备份,但随着用户长期的邮件夹越来越大,到磁盘空间耗尽时,每个用户都会受到损失。使用 POP,就能卸载邮件服务器上保存的消息了。 

什么是MIME 
MIME(Multipurpose Internet Mail Extensions),即多用途Internet邮件扩展标准。它不是邮件传输协议,而是对传输内容的消息、附件及其它的内容定义了格式。这里有很多不同的RFC(Requirement of Comment)文档:RFC 822、RFC 2045、RFC 2046 和 RFC 2047。作为一个 JavaMail API 的用户,您通常不必对这些格式操心。无论如何,一定存在这些格式而且程序会用到它。


下图显示了一个Multipart邮件的结构。



下图显示了一个典型的Multipart邮件的嵌套 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值