Jak odczytać tekst wewnątrz wiadomości za pomocą javax.poczta
Rozwijam pocztę klienta używając javaxa.mail to read mail inside mail box:
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);
}
Wiem, że metoda getContent()
zwraca obiekt, ponieważ zawartość może być String
, a MimeMultiPart
, a SharedByteArrayInputstream
i inne ( myślę )... Czy istnieje sposób, aby zawsze uzyskać tekst wewnątrz wiadomości? Dzięki!!
5 answers
Ta odpowiedź rozszerzaodpowiedź Yurina . Problem, który poruszył, polegał na tym, że Treść MimeMultipart
może być sama w sobie inną MimeMultipart
. Poniższa metoda getTextFromMimeMultipart()
rekursuje w takich przypadkach zawartość do momentu pełnego przetworzenia treści wiadomości.
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-12 09:51:17
Ta odpowiedź rozszerza odpowiedź Austina , aby naprawić oryginalny problem z traktowaniem multipart/alternative
(// without break same text appears twice in my tests
).
Tekst pojawia się dwa razy, ponieważ dla multipart/alternative
, agent użytkownika powinien wybrać tylko jedną część.
From RFC2046 :
Typ "multipart/alternative" jest składniowo identyczny z "multipart / mixed", ale semantyka jest inna. W szczególności każda z części ciała jest "alternatywną" wersją tego samego informacje.
Systemy powinny uznawać, że zawartość poszczególnych części jest wymienna. Systemy powinny wybrać "najlepszy" typ na podstawie lokalnego środowiska i odniesień, w niektórych przypadkach nawet poprzez interakcję z użytkownikiem. Podobnie jak w przypadku "multipart / mixed", kolejność części ciała jest znacząca. W tym przypadku alternatywy pojawiają się w kolejności rosnącej wierności oryginalnej treści. Ogólnie rzecz biorąc, najlepszym wyborem jest ostatnia część typu obsługiwanego przez odbiorcę lokalne środowisko systemu.
Ten sam przykład z leczeniem alternatywnym:
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;
}
Zauważ, że jest to bardzo prosty przykład. Pomija wiele przypadków i nie powinien być używany w produkcji w obecnym formacie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:33
Poniżej znajduje się metoda, która pobiera tekst z wiadomości w przypadku, gdy bodyParts to text i html.
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 "";
}
Update . Istnieje przypadek, że część ciała może być typu multipart. (Spotkałem takiego e-maila po napisaniu tej odpowiedzi.) W tym przypadku będziesz musiał przepisać powyższą metodę z rekurencją.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-08 17:36:49
Nie wydaje mi się, inaczej co by się stało, gdyby typ mime Part
to image/jpeg
? API zwraca Object
, ponieważ wewnętrznie próbuje dać ci coś użytecznego, pod warunkiem, że wiesz, czego oczekujesz. W przypadku oprogramowania ogólnego przeznaczenia jest on przeznaczony do użycia w następujący sposób:
if (part.isMimeType("text/plain")) {
...
} else if (part.isMimeType("multipart/*")) {
...
} else if (part.isMimeType("message/rfc822")) {
...
} else {
...
}
Masz również raw (właściwie nie tak raw , patrz Javadoc) Part.getInputStream()
, ale myślę, że nie jest bezpieczne zakładanie, że każda wiadomość, którą otrzymujesz, jest tekstowa-chyba że jesteś pisząc bardzo konkretną aplikację masz kontrolę nad źródłem danych wejściowych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-28 08:19:01
Jeśli chcesz uzyskać tekst zawsze możesz pominąć inne typy, takie jak 'multipart' itp...
Object body = message.getContent();
if(body instanceof String){
// hey it's a text
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-24 05:51:30