利用 Java Mail 来收发邮件
利用 Java Mail 来收发邮件
本文是由JR主持写作的《J2SE进阶》一书的部分章节整理而成,《J2SE进阶》正在写作、完善阶段。您阅读后,有任何建议、批评,请和我联系,或在
放置附件的注意事项如下:
在发mail时需要注意字符集的问题。不但content里要设置,而且文件名也需要设置。如果我们去掉mbp.setFileName(MimeUtility.encodeWord(fds.getName(),"GB2312",null));这句话,那么你选中的附件还是会带到邮件里,但是在附件里看不到。我们可以通过查看邮件大小知道。我们利用这个特点来实现发送content中写的是html语言,而且包含图片信息的邮件。
大家都知道html语言可以带上图片链接(<img src=c:/test.jpg></img>),那么我们在发送邮件的时候就需要对这些链接的图片做特殊处理。否则在对方接收到邮件的时候会看不到图片。我们特殊处理的方法就是把它们当成附件发送,但不显示在附件里。要做到这些就首先需要对输入的content进行解析,找到所带图片的路径。然后把content中<img src=c:/test.jpg></img>这段代码变成<img src= cid:IMG></img>。我们在发送附件的时候用mbp1.setHeader("Content-ID","IMG") 来把图片和附件对应上。如何具体解析content的操作我就不赘述了,我现在给出如何把修改好的content发送出去的例子。
我们在阅读完邮件后可以给邮件设置删除标志,然后在关闭FOLDER的时候用true来清空已经被标志为删除的邮件。邮件的状态是在类FLAGS.FLAG中定义的。包括如下几种:
我们可以根据不同的需要进行设置,但是需要注意的是,不是所有的服务器都支持这些状态。我们在做操作之前可以用getPermanentFlags方法来得到Message中的状态。参考下面代码
在带有附件的邮件中,消息的内容是Multipart型,这样我们就需要解析它来得到content和附件(它是发送带附件的邮件的逆向过程)。大家在使用outlook、foxmail这些电子邮件客户端的时候会发现,我们的邮件被从服务器上下载下来并且保存到本地硬盘上了,这种方式方便我们离线浏览邮件。在下面的范例中我们也把服务器上的邮件保存到本地。如果有兴趣大家可以编写一个客户端的图形界面来读取保存下来的邮件。
在下面的例子里,我只是向大家介绍如何解析附件。
利用 Java Mail 来收发邮件
本文是由JR主持写作的《J2SE进阶》一书的部分章节整理而成,《J2SE进阶》正在写作、完善阶段。您阅读后,有任何建议、批评,请和我联系,或在
- 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(()
- _mailAttachment.getAttachPath().get(i));
- mbp.setDataHandler(new DataHandler(fds));
- mbp.setFileName(MimeUtility.encodeWord(fds.getName(),
- "GB2312",null));
- mp.addBodyPart(mbp);
- }
- }
- catch(MessagingException ie)
- {
- .out.println("Set Content Message error..."+ie.getMessage());
- throw ie;
- }
- catch(UnsupportedEncodingException ie)
- {
- .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语言可以带上图片链接(<img src=c:/test.jpg></img>),那么我们在发送邮件的时候就需要对这些链接的图片做特殊处理。否则在对方接收到邮件的时候会看不到图片。我们特殊处理的方法就是把它们当成附件发送,但不显示在附件里。要做到这些就首先需要对输入的content进行解析,找到所带图片的路径。然后把content中<img src=c:/test.jpg></img>这段代码变成<img src= cid:IMG></img>。我们在发送附件的时候用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(
- ()_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
- 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))
- .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)
- .out.println("DELETED message");
- else if (sf[i] == Flags.Flag.SEEN)
- .out.println("SEEN message");
- }
4.接收带附件的邮件
在带有附件的邮件中,消息的内容是Multipart型,这样我们就需要解析它来得到content和附件(它是发送带附件的邮件的逆向过程)。大家在使用outlook、foxmail这些电子邮件客户端的时候会发现,我们的邮件被从服务器上下载下来并且保存到本地硬盘上了,这种方式方便我们离线浏览邮件。在下面的范例中我们也把服务器上的邮件保存到本地。如果有兴趣大家可以编写一个客户端的图形界面来读取保存下来的邮件。
在下面的例子里,我只是向大家介绍如何解析附件。
- private void getAttachFile(Part messagePart,BufferedOutputStream writeAttachObj)
- throws IOException, MessagingException
- {
- content = messagePart.getContent() ;
- try
- {
- //这种情况下的邮件都是用multi模式发送的,
- // 这种模式包括有附件的邮件和用html表示content的邮件
- if (content instanceof Multipart)
- {
- Multipart contentTmp = (Multipart) content ;
- //如果是MULTI模式发送的,BodyPart(0).getContent()肯定就是content
- .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 ( ie)
- {
- .out.println("exception====" + ie.getMessage()) ;
- }
- }