javamail读取完整的邮件

转载 2007年10月08日 16:47:00
  Javamail API虽然功能封装的比较完整,但是要写一个能正确显示复杂邮件的程序还有很多逻辑和细节要处理。下面是我最近做一个webmail时整理的 Servlet,基本上可以正确的读取text,HTML,HTML中显示图片及附件。在本servlet中也简单处理了常见的中文问题,包括主题、附件、HTML图片中文、email Address中文。总体感觉有两个难点:1、附件和网页图片的抓取,需要定位数节点nodeid,光用partid是不行的;2、中文分两种情况 Base64和客户端服务器端编码不一致。本程序中实现了3种displayPart()的方法,具体情况不同结合使用效率更高。本程序还有一个未处理的地方就是我在做nodeid的时候最多算10个。当然还有其他问题欢迎指正,来出是为了给后来的初学者作个参考例子,少走弯路。
          import java.io.IOException;
  import java.io.InputStream;
  import java.io.UnsupportedEncodingException;
  import java.util.HashMap;
  import javax.mail.Folder;
  import javax.mail.Message;
  import javax.mail.MessagingException;
  import javax.mail.Multipart;
  import javax.mail.Part;
  import javax.mail.Store;
  import javax.mail.internet.InternetAddress;
  import javax.mail.internet.MimeUtility;
  import javax.servlet.ServletException;
  import javax.servlet.ServletOutputStream;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpSession;
  import chunwei.mail.Login;
  import chunwei.mail.MailUserData;
  /**
  * Servlet implementation class for Servlet: MailServlet
  * Author: luchunwei Email: luchunwei@gmail.com
  */
  public class MailNode extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
  private static final long serialVersionUID = 1L;
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  nodeid="";
  node="0";
  currentnodeid=0;
  url=request.getRequestURL().toString();
  HttpSession ses=request.getSession();
  MailUserData mud=(MailUserData)ses.getAttribute("mud");
  ServletOutputStream out=response.getOutputStream();
  response.setContentType("text/html;charset=GB2312");
  int msgid=-1,partid=-1;
  String partname=null;
  String nodepara=null;
  if (request.getParameter("msgid")!=null)
  msgid=Integer.parseInt(request.getParameter("msgid"));
  msgidStr="msgid="+msgid;
  if (request.getParameter("partid")!=null)
  partid=Integer.parseInt(request.getParameter("partid"));
  if (request.getParameter("partname")!=null)
  partname=new String(request.getParameter("partname").getBytes("ISO-8859-1"),"GB2312");
  if (request.getParameter("node")!=null)
  nodepara=request.getParameter("node");
  System.out.println(nodepara);
  //System.out.println(msgid+":"+partid+":"+partname);
  if (partname!=null){
  //displayImages
  try {
  displayPart(partname,response,out);
  } catch (MessagingException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  return;
  }
  //--------------------------
  if (mud==null){
  Login login=new Login("imap","mail.server.com",-1,"user","password");
  login.login();
  if (login.getResult()==1){
  HttpSession session = request.getSession();
  session.setMaxInactiveInterval(3600);
  session.setAttribute("mud",login.getMud());
  }
  mud=(MailUserData)ses.getAttribute("mud");
  }
  //---------------------------
  if (mud==null){
  out.print("<error>Login First(No Session)</error>");
  } else{
  //Folder folder=mud.getFolder();
  try {
  //------------------------
  Store store=mud.getStore();
  Folder folder=store.getFolder("INBOX");
  folder.open(Folder.READ_ONLY);
  //------------------------
  Message m=folder.getMessage(msgid);
  //if(partid==-1){
  if (nodepara==null){
  //if(!imgs.isEmpty())imgs.clear();
  messageHtml="";
  attachment="";
  recipients=getAllgetRecipients(m);
  out.print(displayMessage(request,m,partid));
  } else{
  displayPart(m,nodepara,response,out);
  }
  } catch (MessagingException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  } catch (Exception e) {
  e.printStackTrace();
  }
  }
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doGet(request,response);
  }
  String stdUrl="";
  String url="";
  String msgidStr="";
  String messageHtml="";
  String attachment="";
  String recipients="";
  String nodeid="";
  int currentnodeid=0;
  String node="";
  HashMap<String,Part> imgs=new HashMap<String,Part>();
  public String displayMessage(HttpServletRequest request,Part p,int partid) throws Exception{
  //System.out.println("Type:"+p.getContentType());
  if (currentnodeid==1&&!node.endsWith("0")){
  nodeid=nodeid.substring(0,(nodeid.length()-2));
  }
  node=nodeid+currentnodeid;
  System.out.println(node);
  if (p.isMimeType("multipart/*")){
  nodeid+=currentnodeid+"-";
  Multipart mp=(Multipart) p.getContent();
  int cnt=mp.getCount();
  String mpct=mp.getContentType().toLowerCase();
  for (int i=0;
  i   i++){
  if (mpct.startsWith("multipart/alternative")&&mp.getBodyPart(i).getContentType().toLowerCase().startsWith("text/plain"))continue;
  currentnodeid=i;
  displayMessage(request,mp.getBodyPart(i),i);
  }
  }
  if (p.isMimeType("text/plain")||p.isMimeType("text/html")){
  if (messageHtml=="") {
  messageHtml=(String)p.getContent();
  //System.out.println(messageHtml);
  } else {
  messageHtml=messageHtml+"
  //System.out.println(messageHtml);
  }
  } else if (p.isMimeType("message/rfc822")) {
  //Nested Message
  //displayMessage(request,(Part)p.getContent(),partid);
  } else{
  if (node.length()>2) node=node.substring(2);
  System.out.println(node);
  String disposition=p.getDisposition();
  //System.out.println("disposition:"+disposition);
  if (disposition!=null&&disposition.equalsIgnoreCase(Part.ATTACHMENT)){
  String filename=getFileName(p);
  //imgs.put(filename,p);
  //attachment全部放入内存,会造成内存膨胀;若及时清空又造成Back回来的页面访问不到Attachment
  //attachment+=","+"<a href='"+url+"/"+filename+"?"+msgidStr+"&partid="+partid+"'>"+filename+"</a>";
  attachment+=","+"<a href='"+url+"/"+filename+"?"+msgidStr+"&node="+node+"'>"+filename+"</a>";
  //attachment+=","+"<a href='"+url+"/"+filename+"?"+"&partname="+getFileName(p)+"'>"+filename+"</a>";
  //System.out.println(attachment);
  } else{
  //if(disposition!=null&&disposition.equalsIgnoreCase(Part.INLINE)){
  if (getCid(p)!=null) {
  //System.out.println("Enter Replace");
  imgs.put(getFileName(p),p);
  //String uri=url+"?"+msgidStr+"&partid="+partid;
  String uri=url+"?"+msgidStr+"&node="+node;
  //String uri=url+"?"+"&partname="+getFileName(p);
  String t=messageHtml.substring(messageHtml.indexOf(getCid(p))-1);
  if (!(t.startsWith("/"")||t.startsWith("/'"))){
  uri="'"+uri+"'";
  }
  messageHtml=messageHtml.replace(getCid(p),uri);
  //System.out.println("cid:"+getCid(p));
  //System.out.println(uri);
  }
  }
  }
  return messageHtml+"attachhncwx="+attachment+recipients;
  }
  public void displayPart(Message m,String node,HttpServletResponse response,ServletOutputStream out)
  throws MessagingException, IOException{
  Part part = getPart(m,node);
  String sct = part.getContentType();
  response.setContentType(sct);
  outPut(part,out);
  }
  private Part getPart(Part m, String nodes) throws NumberFormatException, MessagingException, IOException {
  if (node==null)return m;
  String node=nodes.substring(0,1);
  System.out.println(nodes+" : "+node);
  int nid=Integer.parseInt(node);
  if (m.getContent()==null)System.out.print("no content");
  Part p=((Multipart)m.getContent()).getBodyPart(nid);
  if (nodes.length()>2)nodes=nodes.substring(2);
  else {
  if (nodes.length()==1)nodes="";
  }
  if (nodes.length()>0)p=getPart(p,nodes);
  return p;
  }
  public void displayPart(String partname,HttpServletResponse response, ServletOutputStream out) throws MessagingException, IOException{
  //System.out.println(imgs.keySet()+":"+partname);
  Part part=imgs.get(partname);
  String ct=part.getContentType();
  if (ct!=null) response.setContentType(ct);
  //=====Start push Stream into out
  InputStream in=part.getInputStream();
  ByteArrayOutputStream bos=new ByteArrayOutputStream();
  byte [] buffer=new byte[8192];
  int count=0;
  while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);
  in .close();
  try{
  out.write(bos.toByteArray());
  out.flush();
  } catch(Exception e){
  }
  out.close();
  //=====End
  }
  public void displayPart(Message m,int partid,HttpServletResponse response, ServletOutputStream out) throws MessagingException, IOException{
  Multipart mp = (Multipart)m.getContent();
  Part part = mp.getBodyPart(partid);
  String sct = part.getContentType();
  // ContentType ct = new ContentType(sct);
  response.setContentType(sct);
  if (sct == null) {
  out.println("invalid part");
  return;
  }
  //=====Start push Stream into out
  InputStream in=part.getInputStream();
  ByteArrayOutputStream bos=new ByteArrayOutputStream();
  byte [] buffer=new byte[8192];
  int count=0;
  while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);
  in .close();
  try{
  out.write(bos.toByteArray());
  out.flush();
  } catch(Exception e){
  }
  out.close();
  //=====End
  }
  private String getFileName(Part p) throws MessagingException, UnsupportedEncodingException{
  //System.out.println("filename:");
  String filename=p.getFileName();
  if (filename==null)return null;
  filename=new String(filename.getBytes("ISO-8859-1"),"GB2312");
  int indexStart=filename.toUpperCase().indexOf("=?GB");
  if (indexStart>-1){
  filename=filename.substring(0,indexStart)+MimeUtility.decodeText(filename.substring(indexStart));
  }
  return filename;
  }
  private String getCid(Part p) throws MessagingException{
  String cidraw=null,cid=null;
          String [] headers=p.getHeader("Content-id");
  if (headers!=null && headers.length>0) {
  cidraw=headers[0];
  } else{
  return null;
  }
  if (cidraw.startsWith("<")&&cidraw.endsWith(">")) {
  cid="cid:"+cidraw.substring(1,cidraw.length()-1);
  } else {
  cid="cid:"+cidraw;
  }
  return cid;
  }
  /**
  * 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
  * @throws Exception
  */
  private String getAllgetRecipients(Message m) throws Exception{
  return "mailaddrTo=" +getRecipients(m,"TO")
  +"mailaddrCc="+getRecipients(m,"CC")
  +"mailaddrBcc="+getRecipients(m,"BCC");
  }
  private String getRecipients(Message m,String type) throws Exception {
  StringBuffer mailaddr = new StringBuffer("");
  String addtype = type.toUpperCase();
  InternetAddress[] address = null;
  if (addtype.equals("TO")) {
  address = (InternetAddress[]) m.getRecipients(Message.RecipientType.TO);
  } else if (addtype.equals("CC")) {
  address = (InternetAddress[]) m.getRecipients(Message.RecipientType.CC);
  } else {
  address = (InternetAddress[]) m.getRecipients(Message.RecipientType.BCC);
  }
  if (address != null) {
  for (int i = 0;
  i < address.length; <br >   i++) {
  String email = address[i].getAddress();
  if (email == null)
  email = "";
  else {
  email = MimeUtility.decodeText(email);
  }
  String personal = address[i].getPersonal();
  if (personal == null)
  personal = "";
  else {
  personal = MimeUtility.decodeText(personal);
  }
  mailaddr.append("/""+personal+"/" ");
  mailaddr.append("<");
  mailaddr.append(email);
  mailaddr.append(">");
  mailaddr.append(",");
  }
  }
  if (mailaddr.length()>0)mailaddr.deleteCharAt(mailaddr.length()-1);
  return mailaddr.toString();
  }
  private void outPut(Part part,ServletOutputStream out) throws IOException, MessagingException{
  //=====Start push Stream into out
  InputStream in=part.getInputStream();
  ByteArrayOutputStream bos=new ByteArrayOutputStream();
  byte [] buffer=new byte[8192];
  int count=0;
  while ((count=in.read(buffer))>=0) bos.write(buffer,0,count);
  in .close();
  try{
  out.write(bos.toByteArray());
  out.flush();
  } catch(Exception e){
  }
  out.close();
  //=====End
  }
}
        本文转自
http://java.poac.ac.cn/codeopen/html/jishuwenzhang/JavaEE/2007/0606/458.html  

04. JavaMail 查询/读取邮件

JavaMail 查询邮件列表为了使用JavaMail API 检查或提取电子邮件列表,需要使用 POP 或 IMAP 服务器。要检查并获取邮件,需要文件夹和存储类,主要的步骤如下:获得一个 Sess...
  • Al_assad
  • Al_assad
  • 2017-07-28 02:20:21
  • 1285

JavaMail读取最新邮件

在多次尝试和一些网友的讨论下终于对这一问题有了一点点心得,写出来为以后需要用到这个的兄弟行个方便。当然,有疏漏的地方请高手批示。  1.先说协议。pop3是不支持读取新邮件的,flag也只能用del...
  • yinlei144
  • yinlei144
  • 2012-10-06 10:12:52
  • 1267

javamail定时读取邮箱的未读邮件(imap)

为啥不用pop3而用imap,是因为imap能把邮件设置为已读,而pop3不能; 使用javamail mail.imap读取邮箱的邮件,综合网上的例子,贴出自己实际使用的代码供大家参考: 步...
  • zoufaxiang
  • zoufaxiang
  • 2016-03-10 16:39:46
  • 8244

JavaMail获取邮件内容

import java.io.FileOutputStream; import java.io.InputStream; import java.util.Properties; import jav...
  • saviorzl
  • saviorzl
  • 2016-11-25 11:25:05
  • 5492

借助javaMail来接收邮件之代码篇

1 JavaMail介绍      JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。我们可以基于J...
  • weiguolee
  • weiguolee
  • 2012-04-19 12:52:48
  • 6775

javamail1.6最新版本根据接收时间读取邮件

最近在做一个邮件读取功能,调用的是floder里面的search方法,按照网上百度的,设置接收时间为参数,进行检索,可是检索到的值都为空(代码如下图)。并且我查看了1.6的源码,他的接收时间竟然没有实...
  • qq_19806865
  • qq_19806865
  • 2018-03-29 15:59:41
  • 36

java使用javamail读取邮箱(收件箱为例)

转载地址:http://my.oschina.net/cshuangxi/blog/223417 import java.io.BufferedInputStream; import ja...
  • siscoyeoh
  • siscoyeoh
  • 2015-10-18 13:49:56
  • 4148

javamail邮件内容提取

这几天因为客户有要从邮件里面自动提取内容的需要,所以头痛的看来两天。目前找到两种方法: 第一个是脚本实现,如果你用的是outlook而不是outlook express, 那么就可以用脚本实现,  脚...
  • anyfox
  • anyfox
  • 2007-11-18 19:35:00
  • 1087

javaMail 收取邮件,邮件获取,并保存附件

package com.frame.util; /** * Created by wangyanlong 2017/4/6. */ import java.io.*; import java....
  • xunwei0303
  • xunwei0303
  • 2017-04-06 10:04:08
  • 3604

javaMail解析邮件内容和下载附件

介绍一下JavaMail的Message 它对应JavaMail的Message对象,一个Message对象又会有多个子对象如MultiPart对象,更特殊的是整个邮件内容为一个大的 MultiPa...
  • aassdd_zz
  • aassdd_zz
  • 2012-11-20 16:23:55
  • 17815
收藏助手
不良信息举报
您举报文章:javamail读取完整的邮件
举报原因:
原因补充:

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