2008-09-30 48 views
8

Tôi đã xem tài liệu tham chiếu và Spring dường như có hỗ trợ khá tốt cho việc gửi thư. Tuy nhiên, tôi cần phải đăng nhập vào tài khoản thư, đọc tin nhắn và tải xuống bất kỳ tệp đính kèm nào. Đang tải xuống tệp đính kèm thư được hỗ trợ bởi API thư mùa xuân?tải xuống tệp đính kèm thư bằng Java

Tôi biết bạn có thể làm điều này với API thư của Java, nhưng trong quá khứ tôi thấy rằng rất dài và khó chịu khi làm việc.

EDIT: Tôi đã nhận được nhiều lời chỉ tay về phía hướng dẫn mô tả làm thế nào để gửi mail với file đính kèm, nhưng những gì tôi đang hỏi về là làm thế nào để đọc file đính kèm từ nhận mail.

Chúc mừng, Don

+0

mùa xuân cũng có thể làm tốt - http://static.springframework.org/spring/docs/2.0.x/reference/mail.html
Xem phần 22.3.1. Gửi tài liệu đính kèm và tài nguyên nội tuyến – anjanb

+0

Cảm ơn, nhưng câu hỏi của tôi là về việc đọc tệp đính kèm, không gửi tệp đính kèm. –

+0

Ứng dụng email khách của Apache commons có thể thực hiện các tệp đính kèm khá dễ dàng - http://commons.apache.org/email/userguide.html – anjanb

Trả lời

19

Đây là lớp tôi sử dụng để tải xuống e-mail (có xử lý tệp đính kèm). Bạn sẽ phải lướt qua một số thứ mà nó đang làm (như bỏ qua các lớp ghi nhật ký và ghi cơ sở dữ liệu). Tôi cũng đã đặt tên lại một số gói để dễ đọc.

Ý tưởng chung là tất cả tệp đính kèm được lưu dưới dạng tệp riêng lẻ trong hệ thống tệp và mỗi e-mail được lưu dưới dạng bản ghi trong cơ sở dữ liệu với một bộ bản ghi con trỏ đến tất cả đường dẫn tệp đính kèm.

Tập trung vào phương thức doEMailDownload.

/** 
    * 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

ai cũng có maven pom? – jechaviz

0

Như vậy đến nay, tôi đã chỉ được sử dụng các API JavaMail (và tôi đã hợp lý hạnh phúc với họ vì mục đích của tôi). Nếu gói JavaMail đầy đủ quá nặng đối với bạn, thì công cụ vận chuyển cơ bản có thể được sử dụng mà không cần các lớp trên cùng của gói. Bạn càng thấp trong các ngăn xếp SMTP, POP3 và IMAP, bạn càng phải chuẩn bị sẵn sàng để làm cho chính mình.

Về mặt tươi sáng, bạn cũng sẽ có thể bỏ qua các phần không cần thiết cho ứng dụng của mình.

3

Dưới đây là một lỗi:

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

nó nên là:

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

Cảm ơn @Stevenmcherry cho câu trả lời của bạn

11

tôi làm việc ví dụ của Steven một chút và loại bỏ các các phần của mã cụ thể cho Steven. Mã của tôi sẽ không đọc nội dung của email nếu nó có tệp đính kèm. Điều đó là tốt cho trường hợp của tôi nhưng bạn có thể muốn tinh chỉnh nó hơn nữa cho bạn.

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

} 

Bạn cũng cần hai lớp helper

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

Tôi sử dụng này để kiểm tra các lớp học trên

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

} 

} 

Thông tin thêm có thể được tìm thấy tại http://java.sun.com/developer/onlineTraining/JavaMail/contents.html

+0

Mã hoạt động tốt khi hiển thị văn bản email nhưng không tải xuống bất kỳ tệp đính kèm nào. Tôi đã thử một vài điều nhưng mã không tải xuống bất kỳ tệp đính kèm email nào. Cảm ơn bạn đã đưa ra một giải pháp tốt đẹp để đọc email nhưng sẽ tuyệt vời nếu nó có thể tải xuống tệp đính kèm. –

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

Mã này dành cho việc gửi email, OP yêu cầu đọc email. – Jason

0

tôi đã sử dụng Apache Commons Mail for nhiệm vụ này:

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

Từ một đối tượng DataSource bạn có thể lấy một (API xem: http://docs.oracle.com/javase/6/docs/api/javax/activation/DataSource.html?is-external=true) InputStream (bên cạnh tên và loại) của tập tin đính kèm.

Các vấn đề liên quan