Comment gérer le courrier multipart / alternatif avec JavaMail?
J'ai écrit une application qui récupère tous les e-mails à partir d'une boîte de réception, filtre les e-mails qui contiennent une chaîne de caractères, puis place les e-mails dans une ArrayList.
Après les e-mails sont mis dans la Liste, je suis en train de faire quelque chose avec l'objet et le contenu de ces e-mails. Cela fonctionne tout beau pour les e-mails sans pièce jointe. Mais quand j'ai commencé à utiliser des e-mails avec des pièces jointes de tout cela n'a pas fonctionné comme prévu plus.
C'est mon code:
public void getInhoud(Message msg) throws IOException {
try {
cont = msg.getContent();
} catch (MessagingException ex) {
Logger.getLogger(ReadMailNew.class.getName()).log(Level.SEVERE, null, ex);
}
if (cont instanceof String) {
String body = (String) cont;
} else if (cont instanceof Multipart) {
try {
Multipart mp = (Multipart) msg.getContent();
int mp_count = mp.getCount();
for (int b = 0; b < 1; b++) {
dumpPart(mp.getBodyPart(b));
}
} catch (Exception ex) {
System.out.println("Exception arise at get Content");
ex.printStackTrace();
}
}
}
public void dumpPart(Part p) throws Exception {
email = null;
String contentType = p.getContentType();
System.out.println("dumpPart" + contentType);
InputStream is = p.getInputStream();
if (!(is instanceof BufferedInputStream)) {
is = new BufferedInputStream(is);
}
int c;
final StringWriter sw = new StringWriter();
while ((c = is.read()) != -1) {
sw.write(c);
}
if (!sw.toString().contains("<div>")) {
mpMessage = sw.toString();
getReferentie(mpMessage);
}
}
Le contenu de l'e-mail est stocké dans une Chaîne.
Ce code fonctionne tout va bien lorsque je tente de lire des e-mails sans pièce jointe. Mais si j'utilise un e-mail avec pièce jointe la Chaîne contient également le code HTML et même de l'adhésion de codage. Finalement je veux stocker la pièce jointe et le contenu d'un e-mail, mais ma première priorité est d'obtenir simplement le texte ou d'une pièce jointe HTML de codage.
Maintenant, j'ai essayé une approche différente pour gérer les différentes parties:
public void getInhoud(Message msg) throws IOException {
try {
Object contt = msg.getContent();
if (contt instanceof Multipart) {
System.out.println("Met attachment");
handleMultipart((Multipart) contt);
} else {
handlePart(msg);
System.out.println("Zonder attachment");
}
} catch (MessagingException ex) {
ex.printStackTrace();
}
}
public static void handleMultipart(Multipart multipart)
throws MessagingException, IOException {
for (int i = 0, n = multipart.getCount(); i < n; i++) {
handlePart(multipart.getBodyPart(i));
System.out.println("Count "+n);
}
}
public static void handlePart(Part part)
throws MessagingException, IOException {
String disposition = part.getDisposition();
String contentType = part.getContentType();
if (disposition == null) { //When just body
System.out.println("Null: " + contentType);
//Check if plain
if ((contentType.length() >= 10)
&& (contentType.toLowerCase().substring(
0, 10).equals("text/plain"))) {
part.writeTo(System.out);
} else if ((contentType.length() >= 9)
&& (contentType.toLowerCase().substring(
0, 9).equals("text/html"))) {
part.writeTo(System.out);
} else if ((contentType.length() >= 9)
&& (contentType.toLowerCase().substring(
0, 9).equals("text/html"))) {
System.out.println("Ook html gevonden");
part.writeTo(System.out);
}else{
System.out.println("Other body: " + contentType);
part.writeTo(System.out);
}
} else if (disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
System.out.println("Attachment: " + part.getFileName()
+ " : " + contentType);
} else if (disposition.equalsIgnoreCase(Part.INLINE)) {
System.out.println("Inline: "
+ part.getFileName()
+ " : " + contentType);
} else {
System.out.println("Other: " + disposition);
}
}
C'est ce qui est retourné à partir de la System.out.printlns
Null: multipart/alternative; boundary=047d7b6220720b499504ce3786d7
Other body: multipart/alternative; boundary=047d7b6220720b499504ce3786d7
Content-Type: multipart/alternative; boundary="047d7b6220720b499504ce3786d7"
--047d7b6220720b499504ce3786d7
Content-Type: text/plain; charset="ISO-8859-1"
'Text of the message here in normal text'
--047d7b6220720b499504ce3786d7
Content-Type: text/html; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable
'HTML code of the message'
Cette approche renvoie à la normale de texte de l'e-mail mais aussi le codage HTML de l'e-mail. Je ne comprends vraiment pas pourquoi cela se passe, j'ai googlé, mais il semble comme il n'y a personne d'autre avec ce problème.
Toute aide est appréciée,
Merci!
source d'informationauteur Jef
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé la lecture des e-mail avec le JavaMail bibliothèque beaucoup plus difficile que prévu. Je ne blâme pas l'API JavaMail, plutôt que je blâme ma mauvaise compréhension de La RFC-822 -- la définition officielle de l'e-mail sur Internet.
Comme une expérience de pensée: Considérer le degré de complexité d'un message e-mail peut devenir dans le monde réel. Il est possible de "l'infiniment" intégrer les messages dans les messages. Chaque message peut avoir plusieurs pièces jointes (binaire ou texte explicite). Maintenant, imaginez la complexité de cette structure devient dans l'API JavaMail après l'analyse.
Quelques conseils qui peuvent aider lors de la traversée de l'e-mail avec JavaMail:
Message
Multipart
etBodyPart
tout mettre en œuvrePart
. Si possible, de traiter le tout comme unPart
. Cela permettra générique de la traversée des méthodes pour être construit plus facilement.Ces
Part
méthodes d'aide à traverser:String getContentType()
: Commence avec le type MIME. Vous pourriez être tenté de traiter ce type MIME (avec certains de piratage/coupe/matching), mais ne le font pas. Mieux utiliser cette méthode uniquement à l'intérieur du débogueur pour l'inspection.boolean isMimeType(String)
de match. Lire les docs attentivement afin d'en apprendre au sujet de puissants caractères génériques, tels que"multipart/*"
.Object getContent()
: Peut-êtreinstanceof
:Multipart
-- conteneur pour plus d'Part
sMultipart
puis itérer comme index de base zéro avecint getCount()
etBodyPart getBodyPart(int)
BodyPart
implémentePart
Part.isMimeType("text/plain")
Part.isMimeType("text/html")
Message
(implémentePart
) -- incorporé ou attaché e-mailString
(juste le corps du texte -- texte brut ou HTML)InputStream
(probablement encodée en BASE64 pièce jointe)String getDisposition()
: Valeur peut être nullePart.ATTACHMENT.equalsIgnoreCase(getDisposition())
puis d'appelergetInputStream()
à recevoir des octets de la pièce jointe.Enfin, j'ai trouvé le officiel de la Javadoc exclure tout ce qui dans le
com.sun.mail
paquet (et peut-être plus). Si vous avez besoin de ces, lire le code directement, ou de générer le non filtré Javadocs par télécharger de la source et en cours d'exécutionmvn javadoc:javadoc
dans lemail
module de projet de la le projet.Avez-vous trouvé ces JavaMail de la FAQ?
Suivi de Kevin utiles, des conseils, de l'analyse du contenu de votre email Java les types d'objet à l'égard de leurs noms canoniques (ou les noms simples) peut être utile aussi. Par exemple, à la recherche d'une boîte de réception, j'ai droit maintenant, de 486 messages 399 sont des Chaînes de caractères, et 87 sont MimeMultipart. Ceci suggère que pour mon typique e - mail-une stratégie qui utilise instanceof d'abord épluchez les Chaînes qui est le mieux.
Des Cordes, 394 sont text/plain, et 5 sont text/html. Ce ne sera pas le cas pour la plupart; il est le reflet de mon e-mail se nourrit dans cette boîte de réception.
Mais attendez - plus!!! 🙂 Le HTML se faufile dans la il cependant: 87 Multipart, 70 sont multipart/alternative. Pas de garanties, mais la plupart (si pas tous) sont TEXTE + HTML.
De les 17 autres, en plusieurs parties, par ailleurs, 15 sont multipart/mixed, et les 2 sont multipart/signed.
Mon cas d'utilisation avec cette boîte de réception (et un autre) est principalement de regrouper et d'analyser connus liste de diffusion de contenu. Je ne peux pas ignorer tous les messages, mais une analyse de ce genre m'aide à prendre mon traitement plus efficace.