2012-06-28 10 views
22

Ich bin eine Client-Mail mit javax.mail Entwicklung Mail innerhalb Briefkasten zu lesen:Wie Text innerhalb des Körpers der Post lesen javax.mail mit

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

Ich weiß, dass das Verfahren getContent() ein Objekt Ursache zurückzugibt der Inhalt könnte ein String, ein MimeMultiPart, ein SharedByteArrayInputstream und andere (glaube ich) ... Gibt es eine Möglichkeit, immer den Text im Körper der Nachricht zu bekommen? Vielen Dank!!

+0

Welche Art von Ausgabe erhalten Sie ?? Kann man 'msg.getContentType()' nicht benutzen, um Typ zu identifizieren und Mail basierend auf dem Typ zu verarbeiten? – iNan

+0

Ich muss nicht wissen, welche Art von Typ der Inhalt ist, ich muss nur Text darin kennen – JackTurky

+0

Jede Mail mit unterschiedlichen MIME-Typ muss in einer anderen Weise behandelt werden, um Text zu erhalten. Du musst also mit 'getContentType' wechseln. – iNan

Antwort

37

Diese Antwort erweitert yurin's answer. Das Problem, das er aufgeworfen hat, war, dass der Inhalt einer MimeMultipart selbst eine andere MimeMultipart sein könnte. Die folgende Methode getTextFromMimeMultipart() recursiert in solchen Fällen den Inhalt, bis der Nachrichtentext vollständig analysiert wurde.

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

JFYI: In den JavaMail FAQ von Orcale haben sie "multipart/alternative" anders gehandhabt: http://www.oracle.com/technetwork/java/javamail/faq/index.html#mainbody. Nicht sicher, warum sie es tun, da ich "Multipart" nicht kenne. –

+0

danke, funktionierte wie ein Charme für mich! –

9

Ich glaube nicht, sonst was würde passieren, wenn ein Part Mime-Typ ist image/jpeg? Die API gibt eine Object zurück, weil sie intern versucht, Ihnen etwas Nützliches zu geben, vorausgesetzt, Sie wissen, was erwartet wird. Für allgemeine Zwecke Software, es soll wie folgt verwendet werden:

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

Sie haben auch die rohen (eigentlich nicht so roh finden Sie in der Javadoc) Part.getInputStream(), aber ich denke, dass jeder davon ausgehen, unsicher ist und jeder Die Nachricht, die Sie erhalten, ist eine textbasierte - es sei denn, Sie schreiben eine sehr spezifische Anwendung und Sie haben die Kontrolle über die Eingabequelle.

+1

wie kann ich Teil bekommen? – JackTurky

+2

['javax.mail.Message'] (http://javamail.kenai.com/nonav/javadocs/index.html?javax/mail/Message.html) implementiert die' javax.mail.Part'-Schnittstelle – Raffaele

4

Wenn du einen Text bekommen immer dann kann man andere Arten wie ‚mehrteiliger‘ etc überspringen ...

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

in diesem Wie spring ich richtig? – JackTurky

+1

'instanceOf' nur ein Operator keine Methode in Java und dies gibt nur Subjekt nicht den Nachrichtentext – lakshman

9

Unten finden Methode, wird Text aus Meldung bei Körperteile sind Text und HTML nimmt.

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

aktualisieren. Es gibt einen Fall, dass bodyPart selbst vom Typ multipart sein kann. (Ich habe solche Emails getroffen, nachdem ich diese Antwort geschrieben habe.) In diesem Fall müssen Sie die obige Methode mit Rekursion überschreiben.

+0

' // ohne Pause der gleiche Text erscheint zweimal in meinen Tests' - Dies ist, weil Sie nicht zwischen Multipart/Alternative und unterscheiden "mehrteilig/gemischt". "mehrteilig/alternativ" bedeutet, dass die Teile dieselben Informationen enthalten, jedoch in unterschiedlichen Darstellungen. In diesem Fall wird erwartet, dass der Benutzeragent nur einen auswählt. Siehe [hier] (https://tools.ietf.org/html/rfc2046) – pwrex

+0

@hendlast Danke. – yurin

+0

Willkommen. Ein Beispiel, wie Sie damit umgehen können, finden Sie unten. Im Allgemeinen (per RFC) sollten Sie das letzte Element verwenden, obwohl in diesem Fall reiner Text bevorzugt wird. Daher ist es wahrscheinlich ideal, die Körperteile durchzublättern, um eine Plantextversion zu finden. – pwrex

9

Diese Antwort reicht Austin's answer das ursprüngliche Problem mit der Behandlung von multipart/alternative (// without break same text appears twice in my tests) zu korrigieren.

Der Text wird zweimal angezeigt, da der Benutzeragent für multipart/alternative nur einen Teil auswählen soll.

Von RFC2046:

Die "multipart/alternative" Typ syntaktisch identisch ist "multipart/mixed", aber die Semantik sind unterschiedlich. Insbesondere ist jeder der Körperteile eine "alternative" Version derselben Information.

Systeme sollten erkennen, dass der Inhalt der verschiedenen Teile austauschbar ist. Systeme sollten den "besten" Typ basierend auf der lokalen Umgebung und den Referenzen auswählen, in einigen Fällen sogar durch Benutzerinteraktion. Wie bei "multipart/mixed" ist die Reihenfolge der Körperteile signifikant. In diesem Fall erscheinen die Alternativen in einer Reihenfolge der zunehmenden Treue zu dem ursprünglichen Inhalt. Im Allgemeinen ist die beste Wahl der LETZTE Teil eines Typs, der von der lokalen Umgebung des Empfängersystems unterstützt wird.

gleiches Beispiel mit der Behandlung nach Alternativen:

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

Beachten Sie, dass dies ein sehr einfaches Beispiel. Es vermisst viele Fälle und sollte nicht in der Produktion in seinem aktuellen Format verwendet werden.

+0

java.lang.ClassCastException: javax.mail.util.SharedByteArrayInputStream kann nicht in javax.mail.internet.MimeMultipart umgewandelt werden Ich erhalte diesen Fehler – Jerry

+0

Dies ist ein wirklich gutes Beispiel - das beste derzeit im Internet, danke. – zalberico