2012-06-28 33 views
22

मैं मेल मेल बॉक्स के अंदर पढ़ने के लिए javax.mail का उपयोग कर एक ग्राहक मेल विकासशील हूँ मेल के शरीर के अंदर पाठ पढ़ने के लिए कैसे:javax.mail का उपयोग कर

Properties properties = System.getProperties(); 
properties.setProperty("mail.store.protocol", "imap"); 
try { 
    Session session = Session.getDefaultInstance(properties, null); 
    Store store = session.getStore("pop3");//create store instance 
    store.connect("pop3.domain.it", "mail.it", "*****"); 
    Folder inbox = store.getFolder("inbox"); 
    FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false); 
    inbox.open(Folder.READ_ONLY);//set access type of Inbox 
    Message messages[] = inbox.search(ft); 
    String mail,sub,bodyText=""; 
    Object body; 
    for(Message message:messages) { 
     mail = message.getFrom()[0].toString(); 
     sub = message.getSubject(); 
     body = message.getContent(); 
     //bodyText = body..... 
    } 
} catch (Exception e) { 
    System.out.println(e);  
} 

मुझे पता है कि विधि getContent() एक वस्तु कारण रिटर्न सामग्री String, MimeMultiPart, SharedByteArrayInputstream और अन्य (मुझे लगता है) ... क्या संदेश के शरीर के अंदर हमेशा पाठ प्राप्त करने का कोई तरीका हो सकता है? धन्यवाद!!

+0

आपको किस प्रकार का आउटपुट मिल रहा है ??? क्या आप प्रकार के आधार पर प्रकार और प्रक्रिया मेल की पहचान के लिए 'msg.getContentType()' का उपयोग नहीं कर सकते ?? – iNan

+0

मुझे यह जानने की आवश्यकता नहीं है कि सामग्री किस प्रकार की है, मुझे केवल इसके अंदर पाठ जानने की आवश्यकता है – JackTurky

+0

टेक्स्ट प्राप्त करने के लिए अलग-अलग एमआईएम प्रकार वाले प्रत्येक मेल को अलग-अलग तरीके से संभालना होगा। इसलिए आपको 'getContentType' – iNan

उत्तर

37

यह उत्तर yurin's answer फैलाता है। वह मुद्दा उठाया गया था कि MimeMultipart की सामग्री स्वयं एक और MimeMultipart हो सकती है। getTextFromMimeMultipart() विधि सामग्री पर ऐसे मामलों में रिकर्स करता है जब तक कि संदेश निकाय पूरी तरह से पार्स नहीं किया जाता है।

private String getTextFromMessage(Message message) throws MessagingException, IOException { 
    String result = ""; 
    if (message.isMimeType("text/plain")) { 
     result = message.getContent().toString(); 
    } else if (message.isMimeType("multipart/*")) { 
     MimeMultipart mimeMultipart = (MimeMultipart) message.getContent(); 
     result = getTextFromMimeMultipart(mimeMultipart); 
    } 
    return result; 
} 

private String getTextFromMimeMultipart(
     MimeMultipart mimeMultipart) throws MessagingException, IOException{ 
    String result = ""; 
    int count = mimeMultipart.getCount(); 
    for (int i = 0; i < count; i++) { 
     BodyPart bodyPart = mimeMultipart.getBodyPart(i); 
     if (bodyPart.isMimeType("text/plain")) { 
      result = result + "\n" + bodyPart.getContent(); 
      break; // without break same text appears twice in my tests 
     } else if (bodyPart.isMimeType("text/html")) { 
      String html = (String) bodyPart.getContent(); 
      result = result + "\n" + org.jsoup.Jsoup.parse(html).text(); 
     } else if (bodyPart.getContent() instanceof MimeMultipart){ 
      result = result + getTextFromMimeMultipart((MimeMultipart)bodyPart.getContent()); 
     } 
    } 
    return result; 
} 
+0

जेएफवाईआई: ऑर्केल के जावामेल FAQ में, आपने 'मल्टीपार्ट/वैकल्पिक' को अलग-अलग संभाला है: http://www.oracle.com/technetwork/java/javamail/faq/index.html#mainbody। सुनिश्चित नहीं है कि वे ऐसा क्यों कर रहे हैं, क्योंकि मैं 'मल्टीपार्ट' से परिचित नहीं हूं। –

+0

धन्यवाद, मेरे लिए एक आकर्षण की तरह काम किया! –

9

मुझे ऐसा नहीं लगता है, अन्यथा क्या होगा यदि Part का माइम प्रकार image/jpeg है? एपीआई Object देता है क्योंकि आंतरिक रूप से यह आपको कुछ उपयोगी देने की कोशिश करता है, बशर्ते आप जानते हों कि क्या होने की उम्मीद है। सामान्य प्रयोजन सॉफ्टवेयर के लिए, यह इस तरह से इस्तेमाल किया जा करने का इरादा है:

if (part.isMimeType("text/plain")) { 
    ... 
} else if (part.isMimeType("multipart/*")) { 
    ... 
} else if (part.isMimeType("message/rfc822")) { 
    ... 
} else { 
    ... 
} 

तुम भी (, वास्तव में ऐसा कच्चे नहीं जावाडोक देखें) कच्चे है Part.getInputStream(), लेकिन मुझे लगता है कि यह ग्रहण करने के लिए प्रत्येक और हर कि असुरक्षित है आपको प्राप्त संदेश एक टेक्स्ट-आधारित है - जब तक कि आप एक बहुत ही विशिष्ट एप्लिकेशन लिख रहे हों और आपके पास इनपुट स्रोत पर नियंत्रण हो।

+1

मैं कैसे कर सकता हूं भाग ले लो? – JackTurky

+2

['javax.mail.Message'] (http://javamail.kenai.com/nonav/javadocs/index.html?javax/mail/Message.html) इस में' javax.mail.Part' इंटरफ़ेस – Raffaele

4

आप पाठ पाने के लिए हमेशा तो आप 'बहुखण्डीय' आदि जैसे अन्य प्रकार को छोड़ सकते हैं चाहते हैं ...

Object body = message.getContent(); 
    if(body instanceof String){ 
    // hey it's a text 
    } 
+0

लागू करता है जिस तरह से मैं मेल सच कूदता हूँ? – JackTurky

+1

'instanceOf' सिर्फ एक ऑपरेटर जावा में कोई विधि नहीं है और यह सिर्फ संदेश देता है कि संदेश निकाय – lakshman

9

नीचे विधि है कि पाठ और html मामले bodyparts में संदेश से पाठ लेता होगा है।

import javax.mail.BodyPart; 
    import javax.mail.Message; 
    import javax.mail.internet.MimeMultipart; 
    import org.jsoup.Jsoup; 

    ....  
    private String getTextFromMessage(Message message) throws Exception { 
    if (message.isMimeType("text/plain")){ 
     return message.getContent().toString(); 
    }else if (message.isMimeType("multipart/*")) { 
     String result = ""; 
     MimeMultipart mimeMultipart = (MimeMultipart)message.getContent(); 
     int count = mimeMultipart.getCount(); 
     for (int i = 0; i < count; i ++){ 
      BodyPart bodyPart = mimeMultipart.getBodyPart(i); 
      if (bodyPart.isMimeType("text/plain")){ 
       result = result + "\n" + bodyPart.getContent(); 
       break; //without break same text appears twice in my tests 
      } else if (bodyPart.isMimeType("text/html")){ 
       String html = (String) bodyPart.getContent(); 
       result = result + "\n" + Jsoup.parse(html).text(); 

      } 
     } 
     return result; 
    } 
    return ""; 
} 

अद्यतन। एक मामला है, कि बॉडीपार्ट स्वयं मल्टीपार्ट प्रकार का हो सकता है। (इस जवाब को लिखने के बाद मैंने इस तरह के ईमेल से मुलाकात की।) इस मामले में आपको रिकर्सन के साथ उपरोक्त विधि को फिर से लिखना होगा।

+0

' // बिना किसी ब्रेक के टेक्स्ट मेरे परीक्षणों में दो बार दिखाई देता है - ऐसा इसलिए है क्योंकि आप 'मल्टीपार्ट/वैकल्पिक' के बीच अंतर नहीं कर रहे हैं और 'बहुखण्डीय/mixed'। 'मल्टीपार्ट/वैकल्पिक' का अर्थ है कि भागों में एक ही जानकारी होती है, लेकिन विभिन्न प्रस्तुतियों में। इस मामले में, उपयोगकर्ता एजेंट से केवल एक चुनने की उम्मीद है। [यहां] देखें (https://tools.ietf.org/html/rfc2046) – pwrex

+0

@hendlast धन्यवाद। – yurin

+0

आपका स्वागत है। इस से निपटने के उदाहरण के लिए नीचे देखें। सामान्य रूप से (आरएफसी के अनुसार) आपको अंतिम तत्व लेना चाहिए, हालांकि इस मामले में सादे पाठ को प्राथमिकता दी जाती है ताकि प्लान टेक्स्ट संस्करण खोजने के लिए शरीर के हिस्सों के माध्यम से लूपिंग संभवतः आदर्श हो। – pwrex

9

इस उत्तर Austin's answer फैली multipart/alternative (// without break same text appears twice in my tests) के उपचार के साथ मूल समस्या को ठीक करने के लिए।

पाठ दो बार दिखाई देता है क्योंकि multipart/alternative के लिए, उपयोगकर्ता एजेंट से केवल एक भाग चुनने की उम्मीद है।

RFC2046 से:

"बहुखण्डीय/विकल्प" प्रकार वाक्य रचना समान है करने के लिए "बहुखण्डीय/मिश्रित", लेकिन अर्थ विज्ञान अलग हैं। विशेष रूप से, शरीर के प्रत्येक भाग एक ही जानकारी का एक "वैकल्पिक" संस्करण है।

सिस्टम को यह समझना चाहिए कि विभिन्न हिस्सों की सामग्री एक दूसरे के लिए परिवर्तनीय है। सिस्टम को स्थानीय वातावरण और संदर्भों के आधार पर "सर्वोत्तम" प्रकार का चयन करना चाहिए, कुछ मामलों में भी उपयोगकर्ता इंटरैक्शन के माध्यम से। "मल्टीपार्ट/मिश्रित" के साथ, शरीर के अंगों का क्रम महत्वपूर्ण है। इस मामले में, विकल्प मूल सामग्री के प्रति वफादारी बढ़ाने के क्रम में दिखाई देते हैं। आम तौर पर, सर्वोत्तम विकल्प प्राप्तकर्ता प्रणाली के स्थानीय वातावरण द्वारा समर्थित प्रकार का अंतिम भाग होता है।विकल्प के लिए उपचार के साथ

एक ही उदाहरण:

private String getTextFromMessage(Message message) throws IOException, MessagingException { 
    String result = ""; 
    if (message.isMimeType("text/plain")) { 
     result = message.getContent().toString(); 
    } else if (message.isMimeType("multipart/*")) { 
     MimeMultipart mimeMultipart = (MimeMultipart) message.getContent(); 
     result = getTextFromMimeMultipart(mimeMultipart); 
    } 
    return result; 
} 

private String getTextFromMimeMultipart(
     MimeMultipart mimeMultipart) throws IOException, MessagingException { 

    int count = mimeMultipart.getCount(); 
    if (count == 0) 
     throw new MessagingException("Multipart with no body parts not supported."); 
    boolean multipartAlt = new ContentType(mimeMultipart.getContentType()).match("multipart/alternative"); 
    if (multipartAlt) 
     // alternatives appear in an order of increasing 
     // faithfulness to the original content. Customize as req'd. 
     return getTextFromBodyPart(mimeMultipart.getBodyPart(count - 1)); 
    String result = ""; 
    for (int i = 0; i < count; i++) { 
     BodyPart bodyPart = mimeMultipart.getBodyPart(i); 
     result += getTextFromBodyPart(bodyPart); 
    } 
    return result; 
} 

private String getTextFromBodyPart(
     BodyPart bodyPart) throws IOException, MessagingException { 

    String result = ""; 
    if (bodyPart.isMimeType("text/plain")) { 
     result = (String) bodyPart.getContent(); 
    } else if (bodyPart.isMimeType("text/html")) { 
     String html = (String) bodyPart.getContent(); 
     result = org.jsoup.Jsoup.parse(html).text(); 
    } else if (bodyPart.getContent() instanceof MimeMultipart){ 
     result = getTextFromMimeMultipart((MimeMultipart)bodyPart.getContent()); 
    } 
    return result; 
} 

ध्यान दें कि यह एक बहुत ही सरल उदाहरण है। यह कई मामलों को याद करता है और इसका उत्पादन वर्तमान प्रारूप में नहीं किया जाना चाहिए।

+0

java.lang.ClassCastException: javax.mail.util.SharedByteArrayInputStream को javax.mail.internet पर नहीं डाला जा सकता है। माइम मल्टीपार्ट मुझे यह त्रुटि मिल रही है – Jerry

+0

यह वास्तव में एक महान उदाहरण है - इंटरनेट पर सबसे अच्छा, धन्यवाद। – zalberico