2009-11-17 14 views
89

अब जब मैंने सभी संदेशों को डाउनलोड किया है, और उन्हेंजावा मेल का उपयोग कर अनुलग्नक डाउनलोड करें

Message[] temp; 

पर संग्रहीत करें, मैं उन संदेशों में से प्रत्येक के लिए अनुलग्नकों की सूची कैसे प्राप्त करूं

List<File> attachments; 

नोट: कोई तृतीय पक्ष libs कृपया, बस जावामेल।

+4

यह मेरे लिए एक बहुत ही उपयोगी सवाल था, यह अधिक वोटों के हकदार है! यह पूछने के लिए धन्यवाद। – Yottagray

उत्तर

91

अपवाद हैंडलिंग के बिना, लेकिन यहाँ जाता है:

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

लेकिन एक मिनट प्रतीक्षा करें, क्या हमें यह जांचना नहीं है कि फ़ाइल को सहेजने से पहले (bodyPart.getDisposition() == Part.ATTACHMENT) {} है, ताकि यह ईमेल के शरीर को सहेज न सके? – folone

+2

आप सही हैं, मैंने अपना कोड –

+7

तय कर दिया है StringUtils.isBlank() का उपयोग करने से पढ़ने के लिए और अधिक प्राकृतिक नहीं होगा! StringUtils.isNotBlank? – Kuchi

23

प्रश्न बहुत पुरानी है, लेकिन शायद यह किसी को मदद मिलेगी। मैं डेविड राबिनोवित्ज़ के जवाब का विस्तार करना चाहता हूं।

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

आपको सभी उम्मीदों को वापस नहीं लौटाया जाना चाहिए, क्योंकि आपके पास मेल हो सकता है जहां मिश्रित भाग परिभाषित स्वभाव के बिना है।

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

इसलिए इस मामले में, आप फ़ाइल नाम की जांच भी कर सकते हैं। इस तरह:

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

संपादित

पूरे काम कर रहे .. ऊपर descibed शर्त का उपयोग कोड क्योंकि प्रत्येक भाग एक और भागों और लगाव को संपुटित कर सकते हैं में नेस्ट किया जाना चाहिए, प्रत्यावर्तन सभी भागों के माध्यम से पार करने के लिए इस्तेमाल किया जाता है

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

अभिव्यक्ति फ़ाइल नाम खाली या 'शून्य' के लिए जांच करता है। क्या वो सही है? – Keerthivasan

+0

ऑक्टोपस: हाँ। चेक करता है कि कोई CharSequence खाली नहीं है (""), शून्य नहीं है और केवल व्हाइटस्पेस नहीं है। – mefi

+0

अरे क्या आप बता सकते हैं कि सूची सूची पर कैसे परिवर्तित करें? – kumuda

9

कोड जहां अनुलग्नक फ़ाइल को बचाने के लिए कुछ समय की बचत होती:

javax मेल संस्करण के साथ 1.4 और बाद, आप कह सकते हैं

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

बजाय

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

[जाहिर है] (http://docs.oracle.com/javaee /6/api/javax/mail/internet/MimeBodyPart.html#saveFile(java.lang.String)) 'bodyPart' को पहले' माइमबॉडीपार्ट 'में परिवर्तित किया जाना चाहिए, जैसे: '((माइमबॉडीपार्ट) बॉडीपार्ट)। सेवफाइल ("/tmp/"+ bodyPart.getFileName());' – yair

0

का यहाँ 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

आप बस कॉमन्स आईओ और कॉमन्स लैंग साथ अपाचे कॉमन्स मेल एपीआई MimeMessageParser - getAttachmentList() उपयोग कर सकते हैं।

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 
    } 
} 
संबंधित मुद्दे