2014-12-09 3 views
6

Ich bekomme E-Mails von einem Client, wo sie eine mehrteilige/alternative Nachricht in eine multipart/gemischte Nachricht geschachtelt haben. Wenn ich den Hauptteil der Nachricht erhalte, gibt es einfach die multipart/alternative Ebene zurück, wenn das, was ich wirklich will, der Text/html Teil ist, der in der multipart/Alternative enthalten ist.Parsing Multipart/Mixed mit Multipart/Alternative Körper in Java

Ich habe durch die Javadocs für javax.mail geschaut und ich kann keinen einfachen Weg finden, um den Körper eines Körperteils zu bekommen, der selbst ein mehrteiliges ist oder den ersten mehrteiligen/gemischten Teil überspringt und in das mehrteilige/alternativer Körper, um den Text/html und Text/Plain Stücke zu lesen.

Die E-Mail-Struktur sieht wie folgt aus:

... 
Content-Type: multipart/mixed; 
    boundary="----=_Part_19487_1145362154.1418138792683" 

------=_Part_19487_1145362154.1418138792683 
Content-Type: multipart/alternative; 
    boundary="----=_Part_19486_1391901275.1418138792683" 

------=_Part_19486_1391901275.1418138792683 
Content-Transfer-Encoding: 7bit 
Content-Type: text/plain; charset=ISO-8859-1 

... 

------=_Part_19486_1391901275.1418138792683 
Content-Transfer-Encoding: 7bit 
Content-Type: text/html; charset=ISO-8859-1 

... 

------=_Part_19486_1391901275.1418138792683-- 

------=_Part_19487_1145362154.1418138792683-- 

Dies ist eine übersicht der Code verwendet, um die E-Mails zu analysieren:

Message [] found = fldr.search(searchCondition);   
for (int i = 0; i < found.length; i++) { 
    Message m = found[i]; 
    Object o = m.getContent(); 
    if (o instanceof Multipart) { 
     log.info("**This is a Multipart Message. "); 
     Multipart mp = (Multipart)o; 
     log.info("The Multipart message has " + mp.getCount() + " parts."); 
     for (int j = 0; j < mp.getCount(); j++) { 
      BodyPart b = mp.getBodyPart(j); 

      // Loop if the content type is multipart then get the content that is in that part, 
      // make it the new container and restart the loop in that part of the message. 
      if (b.getContentType().contains("multipart")) { 
       mp = (Multipart)b.getContent(); 
       j = 0; 
       continue; 
      } 

      log.info("This content type is " + b.getContentType()); 

      if(!b.getContentType().contains("text/html")) { 
       continue; 
      } 

      Object o2 = b.getContent(); 
      if (o2 instanceof String) { 
       <do things with content here> 
      } 
     } 
    } 
} 

Es scheint an der zweiten Grenze zu halten, zu stoppen und nicht Parsen alles weitere. Im Falle der obigen Nachricht stoppt es bei boundary = "---- = _ Part_19486_1391901275.1418138792683" und kommt nie zum Text der Nachricht.

+1

Was bedeutet 'log.info (" Dieser Inhaltstyp ist "+ b.getContentType());' geben? – ToYonos

+1

"Dieser Inhaltstyp ist mehrteilig/alternativ;" Wenn es funktioniert, heißt es: "Dieser Inhaltstyp ist text/html; charset = ISO-8859-1" –

+1

Jedes Mal, für jede Schleife drehen? – ToYonos

Antwort

2

In diesem Block:

if (b.getContentType().contains("multipart")) 
{ 
    mp = (Multipart)b.getContent(); 
    j = 0; 
    continue; 
} 

Sie setzen j-0 und die Schleife fragen fortzusetzen, in der Hoffnung es wieder bei Null beginnen. Aber die Inkrementoperation j++ kommt vor und Ihre Schleife beginnt bei 1, nicht 0.

Setzen Sie j auf -1, um Ihr Problem zu lösen.

if (b.getContentType().contains("multipart")) 
{ 
    mp = (Multipart)b.getContent(); 
    j = -1; 
    continue; 
} 
+1

@Psycho_Penguin: Hat es dir geholfen? – ToYonos

+0

Sorry, ich war in den letzten paar Tagen im Urlaub. Bisher funktioniert es in der Testumgebung, aber nicht in der Produktion. –

+0

Seltsam. Bevor es in beiden Umgebungen versagte? – ToYonos

1

Ich habe Ihren Code getestet und für mich auch gescheitert.

In meinem Fall gibt b.getContentType() alle Großbuchstaben zurück (z. B. "TEXT/HTML; Zeichensatz = UTF-8"). Also habe ich das in Kleinbuchstaben konvertiert und es hat funktioniert.

String contentType=b.getContentType().toLowerCase(Locale.ENGLISH); 

if(!contentType.contains("text/html")) { 
    continue; 
} 
+1

Warum ist es, wenn ich den Inhaltstyp in das Protokoll drucke, immer in Kleinbuchstaben? –

+1

Wenn das Kleinbuchstaben ist, kein Problem. Ich denke, es hängt damit zusammen, welche E-Mail-Client-Bibliothek Sie verwenden. Einige E-Mail-Clients geben Großbuchstaben zurück (ich habe die IMAP-Implementierung von Sun mit Google Mail getestet). –