Ich entwickle eine Client-Mail mit javax.mail, um E-Mails im Postfach zu lesen:
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 kenne die Methode getContent() gibt ein Objekt zurück, weil der Inhalt a sein könnte Stringa MimeMultiParta SharedByteArrayInputstream und andere (glaube ich) … Gibt es eine Möglichkeit, immer den Text in den Nachrichtentext zu bekommen? Vielen Dank!!
Was für eine Ausgabe bekommst du??? kannst du nicht nutzen msg.getContentType() zum Identifizieren des Typs und zum Verarbeiten von E-Mails basierend auf dem Typ??
– Raghav
28. Juni 2012 um 8:14 Uhr
Ich muss nicht wissen, um welche Art von Inhalt es sich handelt, ich muss nur den darin enthaltenen Text kennen
– Jayyrus
28. Juni 2012 um 8:16 Uhr
Jede Mail mit einem anderen MIME-Typ muss anders behandelt werden, um Text zu erhalten. Sie müssen also mit wechseln getContentType
– Raghav
28. Juni 2012 um 8:23 Uhr
Hier gibt es eine wirklich seltsame Mischung aus POP3- und IMAP-Sachen.
– dkarp
1. August 2012 um 5:18 Uhr
Siehe auch stackoverflow.com/questions/5628395/…
– Kein Name
1. Oktober 2014 um 14:03 Uhr
Austin
Diese Antwort erweitert Yurins Antwort. Das Problem, das er ansprach, war, dass der Inhalt von a MimeMultipart kann selbst ein anderer sein MimeMultipart. Das getTextFromMimeMultipart() Die folgende Methode wiederholt sich in solchen Fällen auf 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;
}
@AbhishekGupta Der Unterschied ist der für multipart/alternative, soll der Benutzeragent nur einen Teil auswählen, nicht verketten. Der FAQ-Code tut dies, während der obige Code dies nicht tut. Weitere Einzelheiten finden Sie in meiner Antwort unten.
– Hendalst
1. November 2018 um 7:53 Uhr
hendalst
Diese Antwort erweitert Austins Antwort, um das ursprüngliche Problem mit der Behandlung von zu korrigieren multipart/alternative (// without break same text appears twice in my tests).
Der Text erscheint zweimal, weil für multipart/alternativewird erwartet, dass der Benutzeragent nur auswählt eines Teil.
Der Typ „multipart/alternative“ ist syntaktisch identisch mit „multipart/mixed“, aber die Semantik ist unterschiedlich. Insbesondere ist jeder Körperteil 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 Referenzen auswählen, in einigen Fällen sogar durch Benutzerinteraktion. Wie bei „mehrteilig/gemischt“ ist die Reihenfolge der Körperteile von Bedeutung. In diesem Fall erscheinen die Alternativen in einer Reihenfolge zunehmender Treue zum 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 Behandlung für 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 ist. Es übersieht viele Fälle und sollte in seinem aktuellen Format nicht in der Produktion verwendet werden.
java.lang.ClassCastException: javax.mail.util.SharedByteArrayInputStream kann nicht in javax.mail.internet.MimeMultipart umgewandelt werden Ich erhalte diesen Fehler
– Jerry
30. Mai 2017 um 10:29 Uhr
Dies ist ein wirklich großartiges Beispiel – das beste derzeit im Internet, danke.
– Zach Alberico
18. Oktober 2017 um 21:14 Uhr
Für Google Mail gibt dies keinen E-Mail-Text zurück. Es wird immer ein Nullzeiger @ zurückgegeben. String html = (String) bodyPart.getContent(); Was könnte das Problem sein?
– Pfarr
18. Mai 2018 um 22:53 Uhr
Dieses Beispiel funktioniert genau so, wie ich es mir vorgestellt habe. Mail-.eml-Nachrichten können eine komplizierte Hierarchie haben und es sieht so aus, als ob diese Klasse alle Fälle enthalten kann. Außerdem muss ich sagen, diese Bibliothek javax.mail ist schnell und zuverlässig. Gute Wahl.
– Hariprasad
24. Mai 2019 um 12:26 Uhr
Ich verstehe nicht, warum sie nicht zur Verfügung gestellt haben .getParts() über die wir iterieren und dann bestimmen könnten, welche wir wollen. Wir könnten sogar einen Filter machen. Stattdessen müssen wir 0, 1, 2, 3 machen….
– Romulusnr
10. April 2020 um 4:26 Uhr
Erfinden Sie das Rad nicht neu! Sie können einfach Apache Commons Email verwenden (siehe hier)
Kotlin-Beispiel:
fun readHtmlContent(message: MimeMessage) =
MimeMessageParser(message).parse().htmlContent
Wenn eine E-Mail keinen HTML-Inhalt hat, aber einfachen Inhalt (Sie können dies überprüfen, indem Sie hatPlainContent und hasHtmlContent methoden), dann sollten Sie diesen Code verwenden:
fun readPlainContent(message: MimeMessage) =
MimeMessageParser(message).parse().plainContent
Java-Beispiel:
String readHtmlContent(MimeMessage message) throws Exception {
return new MimeMessageParser(message).parse().getHtmlContent();
}
String readPlainContent(MimeMessage message) throws Exception {
return new MimeMessageParser(message).parse().getPlainContent();
}
Das ist einfach genial! Der Java-Teil macht den Trick perfekt und es ist einfach und sauber
– Sammy
11. April 2019 um 15:36 Uhr
Geben Sie diesem Mann eine Auszeichnung! Ich habe drei Tage lang vergeblich versucht, das umzusetzen, was diese Bibliothek im Grunde tut. Danke, Mann! du bist lebensretter 🙂
– Ahmet Eroğlu
17. Juni 2020 um 10:42 Uhr
Jurin
Unten ist eine Methode, die Text aus der Nachricht nimmt, falls BodyParts Text und HTML sind.
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, in dem bodyPart selbst vom Typ multipart sein kann. (Ich habe eine solche E-Mail erhalten, nachdem ich diese Antwort geschrieben habe.) In diesem Fall müssen Sie die obige Methode mit Rekursion neu schreiben.
Ich glaube nicht, was wäre sonst, wenn a PartDer Mime-Typ von ist image/jpeg? Die API gibt eine zurück Object weil es intern versucht, Ihnen etwas Nützliches zu geben, vorausgesetzt, Sie wissen, was erwartet wird. Für Allzweck-Software soll es 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 rohe (eigentlich nicht so rohsiehe Javadoc) Part.getInputStream()aber ich denke, es ist unsicher anzunehmen, dass jede einzelne Nachricht, die Sie erhalten, textbasiert ist – es sei denn, Sie schreiben eine sehr spezifische Anwendung und haben die Kontrolle über die Eingabequelle.
In meinem Fall wollte ich, dass der HTML-Code auch vorhanden ist, und ich habe auch nach einigen bereits erstellten Dienstprogrammen gesucht, also habe ich meinen mit dem folgenden Code repariert
Was für eine Ausgabe bekommst du??? kannst du nicht nutzen
msg.getContentType()
zum Identifizieren des Typs und zum Verarbeiten von E-Mails basierend auf dem Typ??– Raghav
28. Juni 2012 um 8:14 Uhr
Ich muss nicht wissen, um welche Art von Inhalt es sich handelt, ich muss nur den darin enthaltenen Text kennen
– Jayyrus
28. Juni 2012 um 8:16 Uhr
Jede Mail mit einem anderen MIME-Typ muss anders behandelt werden, um Text zu erhalten. Sie müssen also mit wechseln
getContentType
– Raghav
28. Juni 2012 um 8:23 Uhr
Hier gibt es eine wirklich seltsame Mischung aus POP3- und IMAP-Sachen.
– dkarp
1. August 2012 um 5:18 Uhr
Siehe auch stackoverflow.com/questions/5628395/…
– Kein Name
1. Oktober 2014 um 14:03 Uhr