Javamail 多部分排序不正确
Javamail multiparts not ordered correctly
我有一个尝试动态构建 Javamail 消息的应用程序,组装邮件时可用的 Mime body 部分。每张图片的顶部都有一个 'GPC' 图片,然后是一些 HTML 文本 (body),一个由 HTML 构成的闭包,一个 'Brand'图像和结尾的最后部分,也在 HTML 中。可能包含也可能不包含文件附件。如果适用,错误免责声明 (HTML) 可能会出现在第一张图片之前。
免责声明、body、关闭和附件是 body 个部分,而图像是嵌套的多部分,由 HTML 个装有 CID 的容器和图像组成body 零件本身。发送电子邮件后,它在 Gmail 和 Lotus Notes 中显示正确,而在 Outlook (Hotmail) 中,GPC 图像在顶部被品牌图像覆盖。 body 部分的顺序被保留,但图像除外,它们似乎总是回到顶部。
我想不通。在我看来 'parent' 多部分应该是子类型 'Mixed' 因为 body 部分的顺序很重要,而且它们相对不相关,而嵌套的多部分是 'Related'因为一个 body 部分引用了另一个。我的代码:
public MimeMultipart email_content_builder() throws MessagingException {
MimeMultipart mp = new MimeMultipart();
MimeBodyPart txt_part = new MimeBodyPart(), att_part, err_part, gpc_img_location_part, gpc_img_part, brand_img_location_part, brand_img_part, closing_pt1_part, closing_pt2_part;
DataSource att_source, gpc_img_src, brand_img_src;
String gpc_img_container_html, brand_img_container_html;
//Insert error disclaimer, if applicable:
if (!error_disclaimer.isEmpty()) {
err_part = new MimeBodyPart();
err_part.setText(error_disclaimer, "ISO-8859-1", "html");
mp.addBodyPart(err_part);
}
//Insert GPC logo image, if applicable:
if (GPC_logo.length > 0) {
MimeMultipart gpc_imagery_mp = new MimeMultipart("related");
MimeBodyPart gpc_imagery_part = new MimeBodyPart();
//When resizing the GPC image, the height should be roughly 23% of the width; use this factor: .2331
gpc_img_container_html = "<html><body><img src='cid:gpc_logo' height=\"23px\" width=\"100px\"></body></html>";
gpc_img_location_part = new MimeBodyPart();
gpc_img_location_part.setContent(gpc_img_container_html, "text/html");
gpc_imagery_mp.addBodyPart(gpc_img_location_part);
gpc_img_part = new MimeBodyPart();
gpc_img_src = new ByteArrayDataSource(GPC_logo, "image/jpeg");
gpc_img_part.setDataHandler(new DataHandler(gpc_img_src));
gpc_img_part.setHeader("Content-ID", "<gpc_logo>");
gpc_img_part.setDisposition(MimeBodyPart.INLINE);
gpc_imagery_mp.addBodyPart(gpc_img_part);
gpc_imagery_part.setContent(gpc_imagery_mp);
mp.addBodyPart(gpc_imagery_part);
}
//Insert main body of email:
txt_part.setText(body, "ISO-8859-1", "html");
mp.addBodyPart(txt_part);
//Insert the first part of the closing, if applicable:
if (!Closing_Part1.isEmpty()) {
closing_pt1_part = new MimeBodyPart();
closing_pt1_part.setText(Closing_Part1, "ISO-8859-1", "html");
mp.addBodyPart(closing_pt1_part);
}
//Insert brand logo image, if applicable:
if (brand_logo.length > 0) {
MimeMultipart brand_imagery_mp = new MimeMultipart("related");
MimeBodyPart brand_imagery_part = new MimeBodyPart();
//When resizing the brand image, the height should be roughly 43% of the width; use this factor: .4294
brand_img_container_html = "<html><body><img src='cid:brand_logo' height=\"64px\" width=\"150px\"></body></html>";
brand_img_location_part = new MimeBodyPart();
brand_img_location_part.setContent(brand_img_container_html, "text/html");
brand_imagery_mp.addBodyPart(brand_img_location_part);
brand_img_part = new MimeBodyPart();
brand_img_src = new ByteArrayDataSource(brand_logo, "image/jpeg");
brand_img_part.setDataHandler(new DataHandler(brand_img_src));
brand_img_part.setHeader("Content-ID", "<brand_logo>");
brand_img_part.setDisposition(MimeBodyPart.INLINE);
brand_imagery_mp.addBodyPart(brand_img_part);
brand_imagery_part.setContent(brand_imagery_mp);
mp.addBodyPart(brand_imagery_part);
}
//Insert the second part of the closing, if applicable:
if (!Closing_Part2.isEmpty()) {
closing_pt2_part = new MimeBodyPart();
closing_pt2_part.setText(Closing_Part2, "ISO-8859-1", "html");
mp.addBodyPart(closing_pt2_part);
}
//Insert attachments, if applicable:
if (attachments != null) {
for (int j = 0; j < attachments.size(); j++) {
att_part = new MimeBodyPart();
att_source = new FileDataSource((attachments.get(j)).getPath());
att_part.setDataHandler(new DataHandler(att_source));
att_part.setFileName((attachments.get(j)).getPath());
mp.addBodyPart(att_part);
}
}
return mp;
}
您对不同的邮件阅读器如何显示邮件中的多个正文部分的控制非常有限。最好的办法是将所有非附件内容放入单个 text/html 正文部分,使用 html 格式化消息。您可以使用 multipart/related 在消息中包含图片,但在网络上引用图片通常更简单。
我有一个尝试动态构建 Javamail 消息的应用程序,组装邮件时可用的 Mime body 部分。每张图片的顶部都有一个 'GPC' 图片,然后是一些 HTML 文本 (body),一个由 HTML 构成的闭包,一个 'Brand'图像和结尾的最后部分,也在 HTML 中。可能包含也可能不包含文件附件。如果适用,错误免责声明 (HTML) 可能会出现在第一张图片之前。
免责声明、body、关闭和附件是 body 个部分,而图像是嵌套的多部分,由 HTML 个装有 CID 的容器和图像组成body 零件本身。发送电子邮件后,它在 Gmail 和 Lotus Notes 中显示正确,而在 Outlook (Hotmail) 中,GPC 图像在顶部被品牌图像覆盖。 body 部分的顺序被保留,但图像除外,它们似乎总是回到顶部。
我想不通。在我看来 'parent' 多部分应该是子类型 'Mixed' 因为 body 部分的顺序很重要,而且它们相对不相关,而嵌套的多部分是 'Related'因为一个 body 部分引用了另一个。我的代码:
public MimeMultipart email_content_builder() throws MessagingException {
MimeMultipart mp = new MimeMultipart();
MimeBodyPart txt_part = new MimeBodyPart(), att_part, err_part, gpc_img_location_part, gpc_img_part, brand_img_location_part, brand_img_part, closing_pt1_part, closing_pt2_part;
DataSource att_source, gpc_img_src, brand_img_src;
String gpc_img_container_html, brand_img_container_html;
//Insert error disclaimer, if applicable:
if (!error_disclaimer.isEmpty()) {
err_part = new MimeBodyPart();
err_part.setText(error_disclaimer, "ISO-8859-1", "html");
mp.addBodyPart(err_part);
}
//Insert GPC logo image, if applicable:
if (GPC_logo.length > 0) {
MimeMultipart gpc_imagery_mp = new MimeMultipart("related");
MimeBodyPart gpc_imagery_part = new MimeBodyPart();
//When resizing the GPC image, the height should be roughly 23% of the width; use this factor: .2331
gpc_img_container_html = "<html><body><img src='cid:gpc_logo' height=\"23px\" width=\"100px\"></body></html>";
gpc_img_location_part = new MimeBodyPart();
gpc_img_location_part.setContent(gpc_img_container_html, "text/html");
gpc_imagery_mp.addBodyPart(gpc_img_location_part);
gpc_img_part = new MimeBodyPart();
gpc_img_src = new ByteArrayDataSource(GPC_logo, "image/jpeg");
gpc_img_part.setDataHandler(new DataHandler(gpc_img_src));
gpc_img_part.setHeader("Content-ID", "<gpc_logo>");
gpc_img_part.setDisposition(MimeBodyPart.INLINE);
gpc_imagery_mp.addBodyPart(gpc_img_part);
gpc_imagery_part.setContent(gpc_imagery_mp);
mp.addBodyPart(gpc_imagery_part);
}
//Insert main body of email:
txt_part.setText(body, "ISO-8859-1", "html");
mp.addBodyPart(txt_part);
//Insert the first part of the closing, if applicable:
if (!Closing_Part1.isEmpty()) {
closing_pt1_part = new MimeBodyPart();
closing_pt1_part.setText(Closing_Part1, "ISO-8859-1", "html");
mp.addBodyPart(closing_pt1_part);
}
//Insert brand logo image, if applicable:
if (brand_logo.length > 0) {
MimeMultipart brand_imagery_mp = new MimeMultipart("related");
MimeBodyPart brand_imagery_part = new MimeBodyPart();
//When resizing the brand image, the height should be roughly 43% of the width; use this factor: .4294
brand_img_container_html = "<html><body><img src='cid:brand_logo' height=\"64px\" width=\"150px\"></body></html>";
brand_img_location_part = new MimeBodyPart();
brand_img_location_part.setContent(brand_img_container_html, "text/html");
brand_imagery_mp.addBodyPart(brand_img_location_part);
brand_img_part = new MimeBodyPart();
brand_img_src = new ByteArrayDataSource(brand_logo, "image/jpeg");
brand_img_part.setDataHandler(new DataHandler(brand_img_src));
brand_img_part.setHeader("Content-ID", "<brand_logo>");
brand_img_part.setDisposition(MimeBodyPart.INLINE);
brand_imagery_mp.addBodyPart(brand_img_part);
brand_imagery_part.setContent(brand_imagery_mp);
mp.addBodyPart(brand_imagery_part);
}
//Insert the second part of the closing, if applicable:
if (!Closing_Part2.isEmpty()) {
closing_pt2_part = new MimeBodyPart();
closing_pt2_part.setText(Closing_Part2, "ISO-8859-1", "html");
mp.addBodyPart(closing_pt2_part);
}
//Insert attachments, if applicable:
if (attachments != null) {
for (int j = 0; j < attachments.size(); j++) {
att_part = new MimeBodyPart();
att_source = new FileDataSource((attachments.get(j)).getPath());
att_part.setDataHandler(new DataHandler(att_source));
att_part.setFileName((attachments.get(j)).getPath());
mp.addBodyPart(att_part);
}
}
return mp;
}
您对不同的邮件阅读器如何显示邮件中的多个正文部分的控制非常有限。最好的办法是将所有非附件内容放入单个 text/html 正文部分,使用 html 格式化消息。您可以使用 multipart/related 在消息中包含图片,但在网络上引用图片通常更简单。