我有下面的代码,用于使用带有附件和正文部分(消息部分)的Java Mail API发送邮件,但我只获取附件,而不是正文消息。
任何帮助或意见将不胜感激。
public static void sendmail(String to, String from, String url,
String port, final String username, final String password,
String filename) {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "false");
props.put("mail.smtp.host", url);
props.put("mail.smtp.port", port);
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
message.setSubject("HTML mail with images");
message.setContent("<h1>Hello world</h1>", "text/html");
message.setHeader("Content-ID", "<memememe>");
Multipart multipart = new MimeMultipart("related");
BodyPart messageBodyPart = new MimeBodyPart();
System.out.println("file attached is " + filename);
DataSource source = new FileDataSource(filename);
// messageBodyPart.setHeader("Content-ID",Part.ATTACHMENT);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(source.getName());
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart, Part.INLINE);
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException e) {
System.out.println("::::::Error while sending mail...."
+ e.getMessage());
throw new RuntimeException(e);
}
}
答案 0 :(得分:4)
您正在拨打setContent()
两次。只有一个setContent()
可以使用 - 最后一个。
要在邮件中包含多个部分,您需要将内容设置为MimeMultipart
。好吧,你正在这样做 - 但是multipart对象不包括应该是消息体的部分。
如果您想要包含文字和附件的邮件,则可以创建MimeMultipart
(multipart/mixed
,而不是multipart/related
。
以下是如何构建可能的消息的一些示例:
最简单的是带有一些附件的文字。例如,您想将简历发送给某人,所以您写下几个介绍并附上一个或多个文件(求职信,简历):
mime───multipart/mixed─┬─text ├─attachment1 └─attachment2
Multipart / mixed(MimeMultipart
的默认值)表示电子邮件代理将连续显示部件 - 一个接一个地显示。
inline
,并且电子邮件代理能够显示给定的附件类型,则它将显示在消息本身内部 - 最后。attachment
,则它们通常会显示为某种图标或用于保存附件的链接。如果要发送漂亮的HTML邮件,通常包括纯文本版本和HTML版本。这样,即使在不支持HTML的电子邮件阅读器中,收件人也可以阅读它。如果接收者可能视力受损,这将非常有帮助。所以,你需要使用multipart / alternative:
mime───multipart/mixed─┬─multipart/alternative─┬─text/plain │ └─text/html ├─attachment1 └─attachment2
因此,消息内容再次包括三个部分,正文和两个附件。但是正文本身是MimeMultipart(alternative)
,它包含明文版本和HTML版本。请记住将明文放在第一位,将HTML放在第二位,因为约定是邮件代理选择它知道如何显示的最后一个替代方案。
附件将在身体后连续显示,就像之前一样。
现在让我们看看没有“附件”的邮件,但它确实有嵌入HTML中的图像。在这种情况下,邮件代理需要知道附件不仅仅是发送到要下载的阅读器的文件,而是它应该与HTML相关联地显示它们。因此,正确的mime类型为multipart/related
,以显示部件是相关的。在这种情况下,您还需要为其提供正确的内容ID,并在HTML中使用这些内容ID。这不是MIME标准的一部分,但现在通常是HTML邮件的完成方式。
就MIME而言,这样的消息将如下所示:
mime───multipart/alternative─┬─text/plain └─multipart/related─┬─text/html ├─embedded image 1 └─embedded image 2
这次我们没有附件,所以我们可以将multipart / alternative作为我们的顶级内容。它首先具有明文替代方案,如前所述,但第二种方案本身是MimeMultipart("related")
。
在其中,您有HTML部分和两个图像。 HTML及其图像必须始终是同一多部分/相关对象的一部分。
现在,如果您想将文档附加到这样的邮件,即其中包含HTML 和图像的邮件,该怎么办?然后你将使用这样的东西:
mime───multipart/mixed─┬─multipart/alternative─┬─text/plain │ └─multipart/related─┬─text/html │ ├─embedded image 1 │ └─embedded image 2 ├─attachment1 └─attachment2
因此,您的顶级对象是多部分/混合对象,允许您以连续方式为邮件添加附件。消息“body”(multipart / mixed的第一部分)是具有嵌入式multipart / related的multipart / alternative的复杂结构。然后是其他附件。
总结:
MimeMultipart
对象。multipart/mixed
消息的第一部分应该是您的可读消息,其余部分是附件。multipart/alternative
消息提供相同内容的不同显示选项,从最常见的分母到最罕见的演示文稿类型(例如纯文本→HTML→富文本→专有格式)排序,并且收件人的邮件程序选择最后一个一个知道如何展示的。multipart/related
消息通常用于将HTML正文与其内联消息组合在一起。第一部分是HTML,其他部分包含HTML用于其<img src="..." />
标记的Content-ID。答案 1 :(得分:1)
分享完整的代码,以便在下面发送带有正文和附件的自动化测试报告(最新报告)。
public static void sendMail() throws NoSuchProviderException {
Properties prop = System.getProperties();
prop.put("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.host", hostName);
prop.setProperty("mail.user", uName);
prop.setProperty("mail.password", password);
prop.put("mail.smtp.starttls.enable", true);
prop.setProperty("mail.smtp.port", portNo);
prop.put("mail.smtp.auth", "true");
// Setup mail server
Authenticator auth = new PopupAuthenticator();
Session session = Session.getDefaultInstance(prop, auth);
try {
// session.setDebug(true);
Transport transport = session.getTransport();
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromAddr));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddr));
message.setSubject("Automation Execution Results_" + Utility.systemTimeStamp());
BodyPart messageBodyPart = new MimeBodyPart();
BodyPart attachmentPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
String filename = "AutomationTestReport.html";
DataSource source = new FileDataSource(getTheNewestFile(filePath, ".html"));
attachmentPart.setDataHandler(new DataHandler(source));
messageBodyPart.setText("Hi All" + "\n\n" + "Please find the automation test results" + "\n\n" + "Regards,"
+ "\n" + "Testing team");
attachmentPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
multipart.addBodyPart(attachmentPart);
// session.setDebug(true);
message.setContent(multipart);
transport.connect();
Transport.send(message);
transport.close();
System.out.println("Email report sent successfully....");
Logs.Ulog("Email report sent successfully....");
} catch (MessagingException e) {
e.printStackTrace();
System.out.println("Email report sent failed...." + e.getMessage());
Logs.Ulog("Email report sent failed...." + e.getMessage());
}
}
static class PopupAuthenticator extends Authenticator {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(uName, password);
}
}
/**
* Get the newest file for a reports location
*
* @param filePath
* @param ext
* @return
*/
public static File getTheNewestFile(String filePath, String ext) {
File theNewestFile = null;
File dir = new File(filePath);
FileFilter fileFilter = new WildcardFileFilter("AutomationReport_*" + ext);
File[] files = dir.listFiles(fileFilter);
if (files.length > 0) {
/** The newest file comes first **/
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
theNewestFile = files[0];
System.out.println(theNewestFile.getName());
}
return theNewestFile;
}
答案 2 :(得分:1)
在attachmentPart
之前添加messageBodyPartmultipart.addBodyPart(messageBodyPart);
multipart.addBodyPart(attachmentPart);
message.setContent(multipart);
否则,您将身体消息作为附件