복붙노트

[SPRING] Java로 메일 첨부 파일 다운로드

SPRING

Java로 메일 첨부 파일 다운로드

레퍼런스 문서를 살펴 보았고, Spring은 메일을 보내기에 꽤 좋은 지원을하는 것 같다. 그러나 메일 계정에 로그인하고 메시지를 읽고 첨부 파일을 다운로드해야합니다. Spring 메일 API가 지원하는 메일 첨부 파일을 다운로드합니까?

Java Mail API를 사용하여이 작업을 수행 할 수 있다는 것을 알고 있지만 이전에는 매우 자세하고 불쾌한 작업을 수행했습니다.

편집 : 첨부 파일이있는 메일을 보내는 방법을 설명하는 자습서를 가리키는 몇 가지 회신을 받았지만받은 메일에서 첨부 파일을 읽는 방법에 대해 묻습니다.

건배, 님

해결법

  1. ==============================

    1.다음은 전자 메일을 다운로드 할 때 사용하는 클래스입니다 (첨부 파일 처리 포함). 로깅 클래스와 데이터베이스 쓰기를 무시하는 등의 작업을 눈으로 확인해야합니다. 또한 읽기 쉽도록 패키지의 이름을 다시 지정했습니다.

    다음은 전자 메일을 다운로드 할 때 사용하는 클래스입니다 (첨부 파일 처리 포함). 로깅 클래스와 데이터베이스 쓰기를 무시하는 등의 작업을 눈으로 확인해야합니다. 또한 읽기 쉽도록 패키지의 이름을 다시 지정했습니다.

    일반적인 아이디어는 모든 첨부 파일이 파일 시스템에 개별 파일로 저장되며 각 전자 메일은 모든 첨부 파일 경로를 가리키는 하위 레코드 집합과 함께 데이터베이스에 레코드로 저장된다는 것입니다.

    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;
        }
    
    }
    
  2. ==============================

    2.Steven의 예제를 조금 수정하고 Steven의 코드 부분을 제거했습니다. 첨부 파일이 있으면 내 코드에서 이메일 본문을 읽을 수 없습니다. 내 경우에는 괜찮 으면 좋겠지 만 더 나아질 수는 있습니다.

    Steven의 예제를 조금 수정하고 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에서 확인할 수 있습니다.

  3. ==============================

    3.다음은 오류입니다.

    다음은 오류입니다.

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

    그것은해야한다:

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

    귀하의 답변에 @ Stevenmcherry 감사합니다.

  4. ==============================

    4.이 작업을 위해 Apache Commons Mail을 사용했습니다.

    이 작업을 위해 Apache Commons Mail을 사용했습니다.

    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- 외부 = true).

  5. ==============================

    5.지금까지 JavaMail API 만 사용 했었습니다. (제 목적을 위해 상당히 만족했습니다). 전체 JavaMail 패키지가 너무 무거울 경우 기본 전송 엔진을 패키지의 최상위 계층없이 사용할 수 있습니다. SMTP, POP3 및 IMAP 스택이 낮을수록 더 많이 준비해야합니다.

    지금까지 JavaMail API 만 사용 했었습니다. (제 목적을 위해 상당히 만족했습니다). 전체 JavaMail 패키지가 너무 무거울 경우 기본 전송 엔진을 패키지의 최상위 계층없이 사용할 수 있습니다. SMTP, POP3 및 IMAP 스택이 낮을수록 더 많이 준비해야합니다.

    밝은면에서는 응용 프로그램에 필요하지 않은 부분도 무시할 수 있습니다.

  6. ==============================

    6.

    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";
        }
    }
    
  7. from https://stackoverflow.com/questions/155504/download-mail-attachment-with-java by cc-by-sa and MIT license