利用 Java Mail 来收发邮件

原创 2004年09月21日 13:01:00

本文是由JR主持写作的《J2SE进阶》一书的部分章节整理而成,《J2SE进阶》正在写作、完善阶段。《J2SE进阶》写作项目组感谢您阅读本文。

本文摘自雪无痕Blog

随着网络应用的不断推广,电子邮件越来越多的被大家使用。虽然我们往往将电子邮件与 Foxmail、Outlook 这样的电子邮件客户端联系起来,但是往往我们也需要自己编程实现发送接收邮件,例如在一个网站注册用户后网站发出的回执mail,或者在网络购物的时候,在完成订单后的几分钟之内发送确认电子邮件。对于这样的需求,我们不能通过已有的邮件客户端而需要自己编写邮件发送或者处理程序。在这里向大家讲解一下如何利用JavaMail来实现邮件的收发。

注意:本文只打算讨论JavaMail收发带附件邮件的一些技巧,所以只是给出部分代码,更多更精彩的内容,请期待《J2SE进阶》一书。

1.发送带附件的邮件


  我们平时发送的邮件主要可以分解成2大部分,一个是发信人,接信人,主题等邮件标头,另外一部分是邮件内容,它包括了邮件的附件。我们在发送普通邮件的时候content设置的类型是"text/html",带上附件后,我们需要把content的类型设置成Multipart,这时content包括了附件和"text/html"类型的正文。下面的这个告诉大家如何把附件放置到邮件中。

private Multipart getMultipart() throws  MessagingException,UnsupportedEncodingException  { 
   MimeMultipart mp = new MimeMultipart();    
   try    
   {      
      //设置content里的内容      
      MimeBodyPart contentMbp = new MimeBodyPart();      
      //请指定字符集,否则会是乱码      
      contentMbp.setContent(_mailContent.getContent(),
                            "text/html; charset=GB2312");      
      mp.addBodyPart(contentMbp);      
      //添加附件      
      for (int i=0;i<_mailAttachment.getAttachPath().size();i++)
      {        
         MimeBodyPart mbp = new MimeBodyPart();        
         FileDataSource fds = new FileDataSource((String)
           _mailAttachment.getAttachPath().get(i));        
         mbp.setDataHandler(new DataHandler(fds));        
         mbp.setFileName(MimeUtility.encodeWord(fds.getName(),
           "GB2312",null));        
         mp.addBodyPart(mbp);      
      }
   }    
   catch(MessagingException ie)    
   {      
      System.out.println("Set Content Message error..."+ie.getMessage());      
      throw ie;    
   }    
   catch(UnsupportedEncodingException ie)    
   {      
      System.out.println("Encode the fileName error..."+ie.getMessage());      
      throw ie;    
   }    
   return mp;  
}
放置附件的注意事项如下:
  在发mail时需要注意字符集的问题。不但content里要设置,而且文件名也需要设置。如果我们去掉mbp.setFileName(MimeUtility.encodeWord(fds.getName(),"GB2312",null));这句话,那么你选中的附件还是会带到邮件里,但是在附件里看不到。我们可以通过查看邮件大小知道。我们利用这个特点来实现发送content中写的是html语言,而且包含图片信息的邮件。

2.发送content中包含html页面的邮件


大家都知道html语言可以带上图片链接(),那么我们在发送邮件的时候就需要对这些链接的图片做特殊处理。否则在对方接收到邮件的时候会看不到图片。我们特殊处理的方法就是把它们当成附件发送,但不显示在附件里。要做到这些就首先需要对输入的content进行解析,找到所带图片的路径。然后把content中这段代码变成。我们在发送附件的时候用mbp1.setHeader("Content-ID","IMG") 来把图片和附件对应上。如何具体解析content的操作我就不赘述了,我现在给出如何把修改好的content发送出去的例子。

  //对于发送html类型的content。里边包括图片。        
  for(int i=0;i<_mailContent.getImgHash().size();i++)        
  {          
     MimeBodyPart mbp1 = new MimeBodyPart();
     //得到图片的数据
     FileDataSource fds = new FileDataSource(
       (String)_mailContent.getImgHash().get("IMG"+i));          
     //设置到MimeBodyPart中
     mbp1.setDataHandler(new DataHandler(fds));          
     //设置图片附件和html的对应关系
     mbp1.setHeader("Content-ID","IMG"+i);          
     mp.addBodyPart(mbp1);        
  }

3.邮件的状态


  我们在阅读完邮件后可以给邮件设置删除标志,然后在关闭FOLDER的时候用true来清空已经被标志为删除的邮件。邮件的状态是在类FLAGS.FLAG中定义的。包括如下几种:
    Flags.Flag.ANSWERED 
    Flags.Flag.DELETED 
    Flags.Flag.DRAFT 
    Flags.Flag.FLAGGED 
    Flags.Flag.RECENT 
    Flags.Flag.SEEN 
    Flags.Flag.USER 
  
我们可以根据不同的需要进行设置,但是需要注意的是,不是所有的服务器都支持这些状态。我们在做操作之前可以用getPermanentFlags方法来得到Message中的状态。参考下面代码
  
  Message m = folder.getMessage(1); 
  // set the DELETED flag 
  m.setFlag(Flags.Flag.DELETED, true); 
  // Check if DELETED flag is set of this message 
  if (m.isSet(Flags.Flag.DELETED))    
  System.out.println("DELETED message"); 
  // Examine ALL system flags for this message 
  Flags flags = m.getFlags(); 
  Flags.Flag[] sf = flags.getSystemFlags(); 
  for (int i = 0; i < sf.length; i++) 
  {    
     if (sf[i] == Flags.Flag.DELETED)            
        System.out.println("DELETED message");    
     else if (sf[i] == Flags.Flag.SEEN)            
        System.out.println("SEEN message"); 
  }

4.接收带附件的邮件


  在带有附件的邮件中,消息的内容是Multipart型,这样我们就需要解析它来得到content和附件(它是发送带附件的邮件的逆向过程)。大家在使用outlook、foxmail这些电子邮件客户端的时候会发现,我们的邮件被从服务器上下载下来并且保存到本地硬盘上了,这种方式方便我们离线浏览邮件。在下面的范例中我们也把服务器上的邮件保存到本地。如果有兴趣大家可以编写一个客户端的图形界面来读取保存下来的邮件。
  在下面的例子里,我只是向大家介绍如何解析附件。
private void getAttachFile(Part messagePart,BufferedOutputStream writeAttachObj) 
  throws IOException, MessagingException  
{    
   Object content = messagePart.getContent() ;    
   try    
   {      
      //这种情况下的邮件都是用multi模式发送的,
      // 这种模式包括有附件的邮件和用html表示content的邮件      
      if (content instanceof Multipart)      
      {        
         Multipart contentTmp = (Multipart) content ;        
         //如果是MULTI模式发送的,BodyPart(0).getContent()肯定就是content        
         System.out.println("content==" + contentTmp.getBodyPart(0).getContent()) ;        
         //getCount()可以得到content中bodyPart的个数,content就是第一个
         //bodyPart,其它的附件按照顺序类推。但是有的时候附件就是另外一个邮件,
         //而这个邮件里边可能有其他的附件。下面代码用循环对嵌套情况进行解析。
         for (int i = 0 ; i < contentTmp.getCount() ; i++)        
         {          
            if (contentTmp.getBodyPart(i).isMimeType("multipart/*"))          
            {           
               Multipart multipart = (Multipart) 
                 contentTmp.getBodyPart(i).getContent() ;
               //这个地方增加循环是为了解决嵌套附件的情况。
               for (int k = 0 ; k < multipart.getCount() ; k++)            
               {             
                  //content也会存在于INPUTSTREAM中。              
                  saveAttacheFile(multipart.getBodyPart(k).getContentType(),                              
                                  multipart.getBodyPart(k).getDisposition(),                              
                                  multipart.getBodyPart(k).getFileName(),                              
                                  multipart.getBodyPart(k).getInputStream(),                              
                                  writeAttachObj);            
               }          
            }          
            else          
            {            
               saveAttacheFile(contentTmp.getBodyPart(i).getContentType(),                            
                               contentTmp.getBodyPart(i).getDisposition(),                            
                               contentTmp.getBodyPart(i).getFileName(),                            
                               contentTmp.getBodyPart(i).getInputStream(),                            
                               writeAttachObj);          
            }        
         }      
      }      
      //这种情况中邮件是纯文本形式,并且没有附件      
      else      
      {        
         writeAttachObj.write(("content = "+content+"/r/n").getBytes());        
         writeAttachObj.flush();      
      }    
   }    
   catch (Exception ie)    
   {      
      System.out.println("exception====" + ie.getMessage()) ;    
   }  
}
 src=” cid:IMG”>

利用 Java Mail 来收发邮件

google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";...
  • java169
  • java169
  • 2008年05月25日 00:33
  • 201

java mail 收发邮件

java mail 收发邮件   1.发件2.收件   1.发件 package base.util; /* Some SMTP servers require a username and pa...
  • xuqianghit
  • xuqianghit
  • 2010年12月07日 13:53
  • 939

用Emacs接收Exchange邮件

基本思路,首先安装DavMail server版本,将exchange服务转换成标准服务,比如smtp, pop3, imap。然后使用Emacs的mu4e连接DavMail的imap服务。如何安装D...
  • sheismylife
  • sheismylife
  • 2014年11月23日 10:38
  • 3982

linux收发邮件命令

邮件收发及查看 1、将文件当作电子邮件内容送出:    语法:mail –s “主题” user   //将file.c当做mail的内容,发送给user用户。2、传送本地用户电子邮件 语法:mail...
  • junli0310
  • junli0310
  • 2008年07月01日 14:31
  • 1137

centos7 发送邮件给外部邮箱

centos7 发送邮件给外部邮箱
  • jiong210
  • jiong210
  • 2016年11月22日 18:04
  • 5320

WEB使用JavaMail发送邮件

现在很多的网站都提供有用户注册功能, 通常我们注册成功之后就会收到一封来自注册网站的邮件。邮件里面的内容可能包含了我们的注册的用户名和密码以及一个激活账户的超链接等信息。今天我们也来实现一个这样的功能...
  • qq_15646957
  • qq_15646957
  • 2016年09月14日 23:50
  • 1318

centos 下利用mail来发送邮件

先Mark一下,因脚本需要给自己发送邮件,网上搜索后,实现后以博客记之。 第一:安装和mail相关的包。 centos 5下有sendmail,而centos 下有postfix服务。 安装如下: ...
  • ckkboy
  • ckkboy
  • 2017年03月07日 11:27
  • 3865

JavaMail:简单的邮件接收程序

实现了 JavaMail 中邮件内容的创建、邮件的发送,现在就看看怎样接收邮件了。 邮件的接收与邮件的发送的基本操作步骤很类似,邮件的发送需要用到 Transport 类,邮件的接收则需要使用 ...
  • hj7jay
  • hj7jay
  • 2016年03月14日 16:50
  • 2447

javamail读取完整的邮件

Javamail API虽然功能封装的比较完整,但是要写一个能正确显示复杂邮件的程序还有很多逻辑和细节要处理。下面是我最近做一个webmail时整理的 Servlet,基本上可以正确的读取text,H...
  • bananabear
  • bananabear
  • 2007年05月30日 12:54
  • 985

Java之——Java mail邮件开发实战

今天,给大家具体讲讲如何利用java mail实现发送邮箱的功能,不多说了,我们直接进入主题。 一、准备环境 java发送邮件需要3个jar包的支持,分别是activation.jar,addit...
  • l1028386804
  • l1028386804
  • 2016年04月13日 21:19
  • 1599
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用 Java Mail 来收发邮件
举报原因:
原因补充:

(最多只允许输入30个字)