2008-09-30 40 views
8

我看過參考文檔,Spring似乎對發送郵件有很好的支持。但是,我需要登錄到郵件帳戶,閱讀郵件並下載任何附件。是否正在下載Spring郵件API支持的郵件附件?用Java下載郵件附件

我知道你可以用Java Mail API做到這一點,但在過去,我發現它非常繁瑣和不愉快。

編輯:我已經收到了一些回覆朝介紹如何發送帶有附件的郵件教程指指點點,但我要問的是如何讀取附件從收到郵件。

乾杯, 唐

+0

春天可以做得很好 - http://static.springframework.org/spring/docs/2.0.x/reference/mail.html
請參閱第22.3.1節。發送附件和內嵌資源 – anjanb 2008-10-01 01:34:20

+0

謝謝,但我的問題是關於閱讀附件,不發送附件。 – 2008-10-01 13:29:20

+0

Apache公用電子郵件客戶端可以很容易地執行附件 - http://commons.apache.org/email/userguide.html – anjanb 2008-10-01 01:32:17

回答

19

下面是我用來下載電子郵件的類(帶附件處理)。你必須瀏覽一些正在做的事情(比如忽略日誌記錄類和數據庫寫入)。爲了便於閱讀,我還重新命名了一些軟件包。

一般的想法是,所有的附件都作爲單個文件保存在文件系統中,每個電子郵件都作爲記錄保存在數據庫中,並有一組指向所有附件文件路徑的子記錄。

專注於doMailDownload方法。

/** 
    * Copyright (c) 2008 Steven M. Cherry 
    * All rights reserved. 
    */ 
package utils.scheduled; 

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.sql.Timestamp; 
import java.util.Properties; 
import java.util.Vector; 

import javax.mail.Address; 
import javax.mail.Flags; 
import javax.mail.Folder; 
import javax.mail.Message; 
import javax.mail.Multipart; 
import javax.mail.Part; 
import javax.mail.Session; 
import javax.mail.Store; 
import javax.mail.internet.MimeBodyPart; 

import glob.ActionLogicImplementation; 
import glob.IOConn; 
import glob.log.Log; 
import logic.utils.sql.Settings; 
import logic.utils.sqldo.EMail; 
import logic.utils.sqldo.EMailAttach; 

/** 
    * This will connect to our incoming e-mail server and download any e-mails 
    * that are found on the server. The e-mails will be stored for further processing 
    * in our internal database. Attachments will be written out to separate files 
    * and then referred to by the database entries. This is intended to be run by 
    * the scheduler every minute or so. 
    * 
    * @author Steven M. Cherry 
    */ 
public class DownloadEMail implements ActionLogicImplementation { 

    protected String receiving_host; 
    protected String receiving_user; 
    protected String receiving_pass; 
    protected String receiving_protocol; 
    protected boolean receiving_secure; 
    protected String receiving_attachments; 

    /** This will run our logic */ 
    public void ExecuteRequest(IOConn ioc) throws Exception { 
     Log.Trace("Enter"); 

     Log.Debug("Executing DownloadEMail"); 
     ioc.initializeResponseDocument("DownloadEMail"); 

     // pick up our configuration from the server: 
     receiving_host = Settings.getValue(ioc, "server.email.receiving.host"); 
     receiving_user = Settings.getValue(ioc, "server.email.receiving.username"); 
     receiving_pass = Settings.getValue(ioc, "server.email.receiving.password"); 
     receiving_protocol = Settings.getValue(ioc, "server.email.receiving.protocol"); 
     String tmp_secure = Settings.getValue(ioc, "server.email.receiving.secure"); 
     receiving_attachments = Settings.getValue(ioc, "server.email.receiving.attachments"); 

     // sanity check on the parameters: 
     if(receiving_host == null || receiving_host.length() == 0){ 
      ioc.SendReturn(); 
      ioc.Close(); 
      Log.Trace("Exit"); 
      return; // no host defined. 
     } 
     if(receiving_user == null || receiving_user.length() == 0){ 
      ioc.SendReturn(); 
      ioc.Close(); 
      Log.Trace("Exit"); 
      return; // no user defined. 
     } 
     if(receiving_pass == null || receiving_pass.length() == 0){ 
      ioc.SendReturn(); 
      ioc.Close(); 
      Log.Trace("Exit"); 
      return; // no pass defined. 
     } 
     if(receiving_protocol == null || receiving_protocol.length() == 0){ 
      Log.Debug("EMail receiving protocol not defined, defaulting to POP"); 
      receiving_protocol = "POP"; 
     } 
     if(tmp_secure == null || 
      tmp_secure.length() == 0 || 
      tmp_secure.compareToIgnoreCase("false") == 0 || 
      tmp_secure.compareToIgnoreCase("no") == 0 
     ){ 
      receiving_secure = false; 
     } else { 
      receiving_secure = true; 
     } 
     if(receiving_attachments == null || receiving_attachments.length() == 0){ 
      Log.Debug("EMail receiving attachments not defined, defaulting to ./email/attachments/"); 
      receiving_attachments = "./email/attachments/"; 
     } 

     // now do the real work. 
     doEMailDownload(ioc); 

     ioc.SendReturn(); 
     ioc.Close(); 
     Log.Trace("Exit"); 
    } 

    protected void doEMailDownload(IOConn ioc) throws Exception { 
     // Create empty properties 
     Properties props = new Properties(); 
     // Get the session 
     Session session = Session.getInstance(props, null); 

     // Get the store 
     Store store = session.getStore(receiving_protocol); 
     store.connect(receiving_host, receiving_user, receiving_pass); 

     // Get folder 
     Folder folder = store.getFolder("INBOX"); 
     folder.open(Folder.READ_WRITE); 

     try { 

      // Get directory listing 
      Message messages[] = folder.getMessages(); 

      for (int i=0; i < messages.length; i++) { 
       // get the details of the message: 
       EMail email = new EMail(); 
       email.fromaddr = messages[i].getFrom()[0].toString(); 
       Address[] to = messages[i].getRecipients(Message.RecipientType.TO); 
       email.toaddr = ""; 
       for(int j = 0; j < to.length; j++){ 
        email.toaddr += to[j].toString() + "; "; 
       } 
       Address[] cc; 
       try { 
        cc = messages[i].getRecipients(Message.RecipientType.CC); 
       } catch (Exception e){ 
        Log.Warn("Exception retrieving CC addrs: %s", e.getLocalizedMessage()); 
        cc = null; 
       } 
       email.cc = ""; 
       if(cc != null){ 
        for(int j = 0; j < cc.length; j++){ 
         email.cc += cc[j].toString() + "; "; 
        } 
       } 
       email.subject = messages[i].getSubject(); 
       if(messages[i].getReceivedDate() != null){ 
        email.received_when = new Timestamp(messages[i].getReceivedDate().getTime()); 
       } else { 
        email.received_when = new Timestamp((new java.util.Date()).getTime()); 
       } 


       email.body = ""; 
       Vector<EMailAttach> vema = new Vector<EMailAttach>(); 
       Object content = messages[i].getContent(); 
       if(content instanceof java.lang.String){ 
        email.body = (String)content; 
       } else if(content instanceof Multipart){ 
        Multipart mp = (Multipart)content; 

        for (int j=0; j < mp.getCount(); j++) { 
         Part part = mp.getBodyPart(j); 

         String disposition = part.getDisposition(); 

         if (disposition == null) { 
          // Check if plain 
          MimeBodyPart mbp = (MimeBodyPart)part; 
          if (mbp.isMimeType("text/plain")) { 
           Log.Debug("Mime type is plain"); 
           email.body += (String)mbp.getContent(); 
          } else { 
           Log.Debug("Mime type is not plain"); 
           // Special non-attachment cases here of 
           // image/gif, text/html, ... 
           EMailAttach ema = new EMailAttach(); 
           ema.name = decodeName(part.getFileName()); 
           File savedir = new File(receiving_attachments); 
           savedir.mkdirs(); 
           File savefile = File.createTempFile("emailattach", ".atch", savedir); 
           ema.path = savefile.getAbsolutePath(); 
           ema.size = part.getSize(); 
           vema.add(ema); 
           ema.size = saveFile(savefile, part); 
          } 
         } else if ((disposition != null) && 
          (disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE)) 
         ){ 
          // Check if plain 
          MimeBodyPart mbp = (MimeBodyPart)part; 
          if (mbp.isMimeType("text/plain")) { 
           Log.Debug("Mime type is plain"); 
           email.body += (String)mbp.getContent(); 
          } else { 
           Log.Debug("Save file (%s)", part.getFileName()); 
           EMailAttach ema = new EMailAttach(); 
           ema.name = decodeName(part.getFileName()); 
           File savedir = new File(receiving_attachments); 
           savedir.mkdirs(); 
           File savefile = File.createTempFile("emailattach", ".atch", savedir); 
           ema.path = savefile.getAbsolutePath(); 
           ema.size = part.getSize(); 
           vema.add(ema); 
           ema.size = saveFile(savefile, part); 
          } 
         } 
        } 
       } 

       // Insert everything into the database: 
       logic.utils.sql.EMail.insertEMail(ioc, email); 
       for(int j = 0; j < vema.size(); j++){ 
        vema.get(j).emailid = email.id; 
        logic.utils.sql.EMail.insertEMailAttach(ioc, vema.get(j)); 
       } 

       // commit this message and all of it's attachments 
       ioc.getDBConnection().commit(); 

       // Finally delete the message from the server. 
       messages[i].setFlag(Flags.Flag.DELETED, true); 
      } 

      // Close connection 
      folder.close(true); // true tells the mail server to expunge deleted messages. 
      store.close(); 
     } catch (Exception e){ 
      folder.close(true); // true tells the mail server to expunge deleted messages. 
      store.close(); 
      throw e; 
     } 

    } 

    protected int saveFile(File saveFile, Part part) throws Exception { 

     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(saveFile)); 

     byte[] buff = new byte[2048]; 
     InputStream is = part.getInputStream(); 
     int ret = 0, count = 0; 
     while((ret = is.read(buff)) > 0){ 
      bos.write(buff, 0, ret); 
      count += ret; 
     } 
     bos.close(); 
     is.close(); 
     return count; 
    } 

    protected String decodeName(String name) throws Exception { 
     if(name == null || name.length() == 0){ 
      return "unknown"; 
     } 
     String ret = java.net.URLDecoder.decode(name, "UTF-8"); 

     // also check for a few other things in the string: 
     ret = ret.replaceAll("=\\?utf-8\\?q\\?", ""); 
     ret = ret.replaceAll("\\?=", ""); 
     ret = ret.replaceAll("=20", " "); 

     return ret; 
    } 

} 
0

到目前爲止,我只用了JavaMail API的(我一直在與他們相當高興我的目的)。如果完整的JavaMail軟件包對您來說太重,那麼可以在沒有軟件包頂層的情況下使用底層傳輸引擎。 SMTP,POP3和IMAP協議棧越低,您必須爲自己準備的越多。

好的一面,你也可以忽略你的應用程序不需要的部分。

3

這裏是一個錯誤:

else if ((disposition != null) && (disposition.equals(Part.ATTACHMENT) 
|| disposition.equals(Part.INLINE)) 

它應該是:

else if ((disposition.equalsIgnoreCase(Part.ATTACHMENT) 
|| disposition.equalsIgnoreCase(Part.INLINE)) 

感謝@Stevenmcherry你的答案

11

我曾史蒂芬的例子一點點,刪除Steven特有的部分代碼。如果電子郵件含有附件,我的代碼將不會閱讀電子郵件的正文。這對我的情況來說很好,但您可能需要進一步改進以適合您的情況。

package utils; 

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import java.util.Properties; 

import javax.mail.Address; 
import javax.mail.Flags; 
import javax.mail.Folder; 
import javax.mail.Message; 
import javax.mail.Multipart; 
import javax.mail.Part; 
import javax.mail.Session; 
import javax.mail.Store; 
import javax.mail.internet.MimeBodyPart; 

public class IncomingMail { 

public static List<Email> downloadPop3(String host, String user, String pass, String downloadDir) throws Exception { 

    List<Email> emails = new ArrayList<Email>(); 

    // Create empty properties 
    Properties props = new Properties(); 

    // Get the session 
    Session session = Session.getInstance(props, null); 

    // Get the store 
    Store store = session.getStore("pop3"); 
    store.connect(host, user, pass); 

    // Get folder 
    Folder folder = store.getFolder("INBOX"); 
    folder.open(Folder.READ_WRITE); 

    try { 
    // Get directory listing 
    Message messages[] = folder.getMessages(); 
    for (int i = 0; i < messages.length; i++) { 

    Email email = new Email(); 

    // from 
    email.from = messages[i].getFrom()[0].toString(); 

    // to list 
    Address[] toArray = messages[i] .getRecipients(Message.RecipientType.TO); 
    for (Address to : toArray) { email.to.add(to.toString()); } 

    // cc list 
    Address[] ccArray = null; 
    try { 
    ccArray = messages[i] .getRecipients(Message.RecipientType.CC); 
    } catch (Exception e) { ccArray = null; } 
    if (ccArray != null) { 
    for (Address c : ccArray) { 
     email.cc.add(c.toString()); 
    } 
    } 

    // subject 
    email.subject = messages[i].getSubject(); 

    // received date 
    if (messages[i].getReceivedDate() != null) { 
    email.received = messages[i].getReceivedDate(); 
    } else { 
    email.received = new Date(); 
    } 

    // body and attachments 
    email.body = ""; 
    Object content = messages[i].getContent(); 
    if (content instanceof java.lang.String) { 

    email.body = (String) content; 

    } else if (content instanceof Multipart) { 

    Multipart mp = (Multipart) content; 

    for (int j = 0; j < mp.getCount(); j++) { 

     Part part = mp.getBodyPart(j); 
     String disposition = part.getDisposition(); 

     if (disposition == null) { 

     MimeBodyPart mbp = (MimeBodyPart) part; 
     if (mbp.isMimeType("text/plain")) { 
     // Plain 
     email.body += (String) mbp.getContent(); 
     } 

     } else if ((disposition != null) && (disposition.equals(Part.ATTACHMENT) || disposition .equals(Part.INLINE))) { 

     // Check if plain 
     MimeBodyPart mbp = (MimeBodyPart) part; 
     if (mbp.isMimeType("text/plain")) { 
     email.body += (String) mbp.getContent(); 
     } else { 
     EmailAttachment attachment = new EmailAttachment(); 
     attachment.name = decodeName(part.getFileName()); 
     File savedir = new File(downloadDir); 
     savedir.mkdirs(); 
     // File savefile = File.createTempFile("emailattach", ".atch", savedir); 
     File savefile = new File(downloadDir,attachment.name); 
     attachment.path = savefile.getAbsolutePath(); 
     attachment.size = saveFile(savefile, part); 
     email.attachments.add(attachment); 
     } 
     } 
    } // end of multipart for loop 
    } // end messages for loop 

    emails.add(email); 

    // Finally delete the message from the server. 
    messages[i].setFlag(Flags.Flag.DELETED, true); 
    } 

    // Close connection 
    folder.close(true); // true tells the mail server to expunge deleted messages 
    store.close(); 

    } catch (Exception e) { 
    folder.close(true); // true tells the mail server to expunge deleted 
    store.close(); 
    throw e; 
    } 

    return emails; 
} 

private static String decodeName(String name) throws Exception { 
    if (name == null || name.length() == 0) { 
    return "unknown"; 
    } 
    String ret = java.net.URLDecoder.decode(name, "UTF-8"); 

    // also check for a few other things in the string: 
    ret = ret.replaceAll("=\\?utf-8\\?q\\?", ""); 
    ret = ret.replaceAll("\\?=", ""); 
    ret = ret.replaceAll("=20", " "); 

    return ret; 
} 

private static int saveFile(File saveFile, Part part) throws Exception { 

    BufferedOutputStream bos = new BufferedOutputStream(
    new FileOutputStream(saveFile)); 

    byte[] buff = new byte[2048]; 
    InputStream is = part.getInputStream(); 
    int ret = 0, count = 0; 
    while ((ret = is.read(buff)) > 0) { 
    bos.write(buff, 0, ret); 
    count += ret; 
    } 
    bos.close(); 
    is.close(); 
    return count; 
} 

} 

你還需要這兩個輔助類

package utils; 

import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 

public class Email { 

public Date received; 
public String from; 
public List<String> to = new ArrayList<String>(); 
public List<String> cc = new ArrayList<String>(); 
public String subject; 
public String body; 
public List<EmailAttachment> attachments = new ArrayList<EmailAttachment>(); 
} 

package utils; 

public class EmailAttachment { 

public String name; 
public String path; 
public int size; 
} 

我用它來測試上述類

package utils; 

import java.util.List; 


public class Test { 

public static void main(String[] args) { 

    String host = "some host"; 
    String user = "some user"; 
    String pass = "some pass"; 
    String downloadDir = "/Temp"; 
    try { 
    List<Email> emails = IncomingMail.downloadPop3(host, user, pass, downloadDir); 
    for (Email email : emails) { 
    System.out.println(email.from); 
    System.out.println(email.subject); 
    System.out.println(email.body); 
    List<EmailAttachment> attachments = email.attachments; 
    for (EmailAttachment attachment : attachments) { 
    System.out.println(attachment.path+" "+attachment.name); 
    } 
    } 
    } catch (Exception e) { e.printStackTrace(); } 

} 

} 

更多信息,可以發現http://java.sun.com/developer/onlineTraining/JavaMail/contents.html

0
import java.io.IOException; 
import java.io.InputStream; 

import javax.mail.internet.MimeMessage; 
import javax.servlet.http.HttpServletRequest; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.core.io.InputStreamSource; 
import org.springframework.mail.javamail.JavaMailSender; 
import org.springframework.mail.javamail.MimeMessageHelper; 
import org.springframework.mail.javamail.MimeMessagePreparator; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.multipart.commons.CommonsMultipartFile; 

@Controller 
@RequestMapping("/sendEmail.do") 
public class SendEmailAttachController { 
    @Autowired 
    private JavaMailSender mailSender; 

    @RequestMapping(method = RequestMethod.POST) 
    public String sendEmail(HttpServletRequest request, 
      final @RequestParam CommonsMultipartFile attachFile) { 

     // Input here 
     final String emailTo = request.getParameter("mailTo"); 
     final String subject = request.getParameter("subject"); 
     final String yourmailid = request.getParameter("yourmail"); 
     final String message = request.getParameter("message"); 

     // Logging 
     System.out.println("emailTo: " + emailTo); 
     System.out.println("subject: " + subject); 
     System.out.println("Your mail id is: "+yourmailid); 
     System.out.println("message: " + message); 
     System.out.println("attachFile: " + attachFile.getOriginalFilename()); 

     mailSender.send(new MimeMessagePreparator() { 

      @Override 
      public void prepare(MimeMessage mimeMessage) throws Exception { 
       MimeMessageHelper messageHelper = new MimeMessageHelper(
         mimeMessage, true, "UTF-8"); 
       messageHelper.setTo(emailTo); 
       messageHelper.setSubject(subject); 
       messageHelper.setReplyTo(yourmailid); 
       messageHelper.setText(message); 

       // Attachment with mail 
       String attachName = attachFile.getOriginalFilename(); 
       if (!attachFile.equals("")) { 

        messageHelper.addAttachment(attachName, new InputStreamSource() { 

         @Override 
         public InputStream getInputStream() throws IOException { 
          return attachFile.getInputStream(); 
         } 
        }); 
       } 

      } 

     }); 

     return "Result"; 
    } 
} 
0

我使用Apache的百科全書郵件此任務:

import java.util.List; 
import javax.activation.DataSource; 
import javax.mail.internet.MimeMessage; 
import org.apache.commons.mail.util.MimeMessageParser; 

public List<DataSource> getAttachmentList(MimeMessage message) throws Exception { 
    msgParser = new MimeMessageParser(message); 
    msgParser.parse(); 
    return msgParser.getAttachmentList(); 
} 

DataSource對象,你可以檢索InputStream附件的(名稱和類型旁邊)(見API:http://docs.oracle.com/javase/6/docs/api/javax/activation/DataSource.html?is-external=true)。