2009-11-17 5 views
89

Maintenant que tous les passe téléchargé les messages et les stocker àTélécharger les pièces jointes en utilisant JavaMail

Message[] temp; 

Comment puis-je obtenir la liste des pièces jointes pour chacun de ces messages à

List<File> attachments; 

Remarque: aucune bibliothèque tierce, s'il vous plaît, juste JavaMail.

+4

C'était une question très utile pour moi, elle mérite plus de votes! Merci de l'avoir demandé. – Yottagray

Répondre

91

Sans la gestion des exceptions, mais voilà:

List<File> attachments = new ArrayList<File>(); 
for (Message message : temp) { 
    Multipart multipart = (Multipart) message.getContent(); 

    for (int i = 0; i < multipart.getCount(); i++) { 
     BodyPart bodyPart = multipart.getBodyPart(i); 
     if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) && 
       StringUtils.isBlank(bodyPart.getFileName())) { 
      continue; // dealing with attachments only 
     } 
     InputStream is = bodyPart.getInputStream(); 
     File f = new File("/tmp/" + bodyPart.getFileName()); 
     FileOutputStream fos = new FileOutputStream(f); 
     byte[] buf = new byte[4096]; 
     int bytesRead; 
     while((bytesRead = is.read(buf))!=-1) { 
      fos.write(buf, 0, bytesRead); 
     } 
     fos.close(); 
     attachments.add(f); 
    } 
} 
+2

Mais attendez une minute, n'est-ce pas censé vérifier if (bodyPart.getDisposition() == Part.ATTACHMENT) {} avant d'enregistrer le fichier, afin qu'il n'enregistre pas le corps de l'email? – folone

+2

Vous avez raison, j'ai corrigé mon code –

+7

StringUtils.isBlank() ne serait-il pas plus naturel à lire qu'à utiliser! StringUtils.isNotBlank? – Kuchi

23

question est très ancienne, mais peut-être cela aidera quelqu'un. Je voudrais développer la réponse de David Rabinowitz.

if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) 

ne devrait pas retourner tous les atachments que vous attendez, parce que vous pouvez avoir la poste où une partie mixte est sans disposition définie.

----boundary_328630_1e15ac03-e817-4763-af99-d4b23cfdb600 
Content-Type: application/octet-stream; 
    name="00000000009661222736_236225959_20130731-7.txt" 
Content-Transfer-Encoding: base64 

Dans ce cas, vous pouvez également vérifier le nom du fichier. Comme ceci:

if (!Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) && StringUtils.isBlank(part.getFileName())) {...} 

EDIT

il y a du code de travail tout en utilisant la condition décrivaient ci-dessus .. Parce que chaque partie peut encapsuler une autre des parties et la fixation doit être imbriquée dans récursivité est utilisé pour traverser à travers toutes les parties

public List<InputStream> getAttachments(Message message) throws Exception { 
    Object content = message.getContent(); 
    if (content instanceof String) 
     return null;   

    if (content instanceof Multipart) { 
     Multipart multipart = (Multipart) content; 
     List<InputStream> result = new ArrayList<InputStream>(); 

     for (int i = 0; i < multipart.getCount(); i++) { 
      result.addAll(getAttachments(multipart.getBodyPart(i))); 
     } 
     return result; 

    } 
    return null; 
} 

private List<InputStream> getAttachments(BodyPart part) throws Exception { 
    List<InputStream> result = new ArrayList<InputStream>(); 
    Object content = part.getContent(); 
    if (content instanceof InputStream || content instanceof String) { 
     if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) || StringUtils.isNotBlank(part.getFileName())) { 
      result.add(part.getInputStream()); 
      return result; 
     } else { 
      return new ArrayList<InputStream>(); 
     } 
    } 

    if (content instanceof Multipart) { 
      Multipart multipart = (Multipart) content; 
      for (int i = 0; i < multipart.getCount(); i++) { 
       BodyPart bodyPart = multipart.getBodyPart(i); 
       result.addAll(getAttachments(bodyPart)); 
      } 
    } 
    return result; 
} 
+0

l'expression recherche le nom de fichier vide ou "null". Est-ce exact? – Keerthivasan

+0

Octopus: Oui. Vérifie si une séquence CharSequence n'est pas vide (""), pas null et pas uniquement les espaces. – mefi

+0

Hey pouvez-vous dire comment convertir la Liste à la liste ? – kumuda

9

Certains gain de temps pour le code où vous enregistrez le fichier de pièce jointe:

avec la version électronique javax 1.4 et après, vous pouvez dire

bodyPart.saveFile("/tmp/" + bodyPart.getFileName()); 

au lieu de

InputStream is = bodyPart.getInputStream(); 
    File f = new File("/tmp/" + bodyPart.getFileName()); 
    FileOutputStream fos = new FileOutputStream(f); 
    byte[] buf = new byte[4096]; 
    int bytesRead; 
    while((bytesRead = is.read(buf))!=-1) { 
     fos.write(buf, 0, bytesRead); 
    } 
    fos.close(); 
+3

[Apparemment] (http://docs.oracle.com/javaee /6/api/javax/mail/internet/MimeBodyPart.html#saveFile(java.lang.String)) 'bodyPart' devrait d'abord être converti en' MimeBodyPart', comme: '((MimeBodyPart) bodyPart) .saveFile ("/tmp/"+ bodyPart.getFileName())" – yair

0

Voici mon interprétation de mefi's solution.

private static void attachments(
    final BodyPart body, final BiConsumer<String, InputStream> consumer) 
    throws MessagingException, IOException { 
    final Multipart content; 
    try { 
     content = (Multipart) body.getContent(); 
     for (int i = 0; i < content.getCount(); i++) { 
      attachments(content.getBodyPart(i), consumer); 
     } 
     return; 
    } catch (final ClassCastException cce) { 
    } 
    if (!Part.ATTACHMENT.equalsIgnoreCase(body.getDisposition())) { 
     return; 
    } 
    final String name = body.getFileName(); 
    if (name == null || name.trim().isEmpty()) { 
     return; 
    } 
    try (final InputStream stream = body.getInputStream()) { 
     consumer.accept(name, stream); 
    } 
} 

public static void attachments(
    final Message message, final BiConsumer<String, InputStream> consumer) 
    throws IOException, MessagingException { 
    final Multipart content; 
    try { 
     content = (Multipart) message.getContent(); 
    } catch (final ClassCastException cce) { 
     return; 
    } 
    for (int i = 0; i < content.getCount(); i++) { 
     attachments(content.getBodyPart(i), consumer); 
    } 
} 
2

Vous pouvez simplement utiliser l'API Apache Commons Courrier MimeMessageParser - getAttachmentList() le long Commons IO et Commons Lang.

MimeMessageParser parser = .... 
parser.parse(); 
for(DataSource dataSource : parser.getAttachmentList()) { 

    if (StringUtils.isNotBlank(dataSource.getName())) {} 

     //use apache commons IOUtils to save attachments 
     IOUtils.copy(dataSource.getInputStream(), ..dataSource.getName()...) 
    } else { 
     //handle how you would want attachments without file names 
     //ex. mails within emails have no file name 
    } 
} 
Questions connexes