У меня есть код для отправки почты с использованием 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);
}
}
Вы вызываете setContent()
дважды. Будет работать только один setContent()
- последний.
Чтобы иметь более одной части вашего сообщения, вам нужно установить контент в MimeMultipart
. Ну, вы это делаете, но многочастный объект не включает часть, которая должна быть телом сообщения.
Если вам требуется сообщение с текстом и вложением, вы создаете MimeMultipart
(multipart/mixed
, а не multipart/related
как вы это делали).
Вот несколько примеров того, как структурировать возможные сообщения:
Самый простой из них - текст с несколькими вложениями. Например, вы хотите отправить свое резюме кому-то, поэтому вы пишете несколько слов о введении и приложите один или несколько документов (сопроводительное письмо, CV):
mime───multipart/mixed─┬─text ├─attachment1 └─attachment2
Multipart/mixed (по умолчанию для MimeMultipart
) означает, что агент электронной почты будет показывать детали поочередно - один за другим.
inline
, а агент электронной почты способен отображать данный тип вложения, он будет отображаться внутри самого сообщения - в конце.attachment
- это 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
, чтобы показать, что части связаны. В этом случае вам также необходимо предоставить им правильные идентификаторы контента и использовать эти идентификаторы контента в HTML. Это не является частью стандарта 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
Таким образом, ваш объект верхнего уровня является multipart/mixed, что позволяет добавлять вложения последовательно к вашему сообщению. Сообщение "тело" (первая часть многочастного/смешанного) представляет собой сложную структуру multipart/alternative со встроенным multipart/related. И затем следуют другие приложения.
В итоге:
MimeMultipart
.multipart/mixed
сообщении есть первая часть, которая должна быть вашим читаемым сообщением, а остальные - вложениями.multipart/alternative
сообщение предоставляет различные альтернативы отображения одного и того же контента, упорядоченные из наиболее распространенного знаменателя, к наиболее редкому типу презентации (например, текст в виде обычного текста → HTML → богатый текст → проприетарное форматирование), а почтовая программа получателя выбирает последнюю, которая знает, как для отображения.multipart/related
обычно используется для объединения тела HTML с его встроенными сообщениями. Первая часть - это HTML, другие части содержат Content-ID, которые HTML использует для тегов <img src="..."/>
.Добавить сообщениеBodyPart перед вложениемПарт
multipart.addBodyPart(messageBodyPart);
multipart.addBodyPart(attachmentPart);
message.setContent(multipart);
В противном случае вы получаете сообщение тела как вложение
Совместное использование полного кода для отправки отчета об автоматическом тестировании с помощью основного текста и вложения (последний отчет прилагается) ниже.
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;
}
setContent()
дважды. Второй вызов заменяет контент, который был установлен в первом вызове.