GWT Java email - java.io.UnsupportedEncodingException: text/html - java

I am sending an email with html text and an attachment and getting the error:
java.io.UnsupportedEncodingException: text/html
The code is:
public void emailMessage(String emailSubject, String message, String emailaddress, String imagePath) {
//Send an email
try {
//Send an email
SimpleEmail email = new SimpleEmail();
email.setHostName("mail.org");
email.setSmtpPort(25); //No authentication required
email.setFrom("address.org");
email.addTo(emailaddress);
email.setSubject(emailSubject);
email.setCharset("utf-8");
// Set the email message text.
MimeBodyPart messagePart = new MimeBodyPart();
messagePart.setText(message, "text/html");
// Set the email attachment file
FileDataSource fileDataSource = new FileDataSource(imagePath);
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.setDataHandler(new DataHandler(fileDataSource));
attachmentPart.setFileName(fileDataSource.getName());
// Create Multipart E-Mail.
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(messagePart);
multipart.addBodyPart(attachmentPart);
email.setContent(multipart);
//Send the email
email.send();
} catch (EmailException e) {
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Initially I was sending an email without an attachment which worked. Then I added the multipart for the attachment and the text/html is no longer valid.

Try
textPart.setText(text, "utf-8" );
or
htmlPart.setContent(html, "text/html; charset=utf-8" );

This worked for me with java >= 8:
MimeMessage msg = new MimeMessage(session)
msg.setContent(content, "text/html")
use setContent instead setText

Related

Sending string as an attachment using javamail gets duplicated content

I'm struggling to send a csv file over javamail.
Since the content is small, I constructed manually the data as CSV format, stored in memory and passed as ByteArrayDataSource to MimeMessageHelper. However, the received file has strangely double the content.
The code is pretty standard:
// mail sender
try {
MimeMessage mail = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mail, true, "UTF-8");
helper.setSubject(mailObj.getMailSubject());
helper.setFrom(mailObj.getMailFrom());
helper.setTo(mailObj.getMailTo());
Mail.Attachment attachment = mailObj.getAttachment();
if (attachment != null) helper.addAttachment(attachment.getFilename(),
attachment.getDataSource());
javaMailSender.send(helper.getMimeMessage());
} catch (Exception e) {
log.error("Cannot send email " + mailObj.toString(), e);
}
DataSource createDataSource(Data originalData) throws IOException {
try (StringWriter out = new StringWriter(); PrintWriter pw = new PrintWriter(out) {
#Override
public void println() {
write(LINE_SEP);
}
}) {
pw.write('\uFEFF'); // Write BOM
pw.println(HEADERS);
for (AppointmentBookingEvent details : appointments) {
// Concatenate the data with PrintWriter.println(...);
}
return new ByteArrayDataSource(out.toString().getBytes(StandardCharsets.UTF_8), "text/csv");
}
}
I noticed that the method DataSource.getInputStream() is called twice by the sender's internal functions. Was that by any chance the cause ?
It seems the problem came from MimeMessageHelper. I could not figure exactly where but the problem has gone when I explicitly constructed the body parts of mail.
MimeMessage mail = javaMailSender.createMimeMessage();
mail.setFrom(new InternetAddress(mailObj.getMailFrom()));
mail.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mailObj.getMailTo()));
mail.setSubject(mailObj.getMailSubject());
Multipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(getContentFromTemplate(mailObj.getModel(), mailObj.getLang(), mailObj.getTemplateName()), "text/html; charset=UTF-8");
multipart.addBodyPart(messageBodyPart);
Mail.Attachment attachment = mailObj.getAttachment();
if (attachment != null) {
BodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart.setFileName(attachment.getFilename());
attachmentBodyPart.setDisposition(Part.ATTACHMENT);
attachmentBodyPart.setDataHandler(new DataHandler(attachment.getDataSource()));
multipart.addBodyPart(attachmentBodyPart);
}
mail.setContent(multipart);
javaMailSender.send(mail);

What would be the error of the email method?

The previous settings of port, authentication, and protocol are correct for you sending the email.
And as a result i get a message like the one in the image.
Without a message and without attachment, I just get the signature by default in the mail.
thanks;
#Autowired
public Session emailSession;
#Override
public JsonObject sendEmail(final JsonObject json) throws CommunicationsException {
final JsonObject response = new JsonObject();
final String receiver = (String) json.get(RECEIVER);
final String subject = (String) json.get(SUBJECT);
final String messageBody = (String) json.get(MESSAGE_BODY);
final String attachment = (String) json.get(ATTACHMENT);
try {
MimeMessage msg = new MimeMessage(emailSession);
msg.setFrom(new InternetAddress(MAIL_USER_FROM));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(receiver));
msg.setSubject(subject);
Multipart emailContenido = new MimeMultipart();
// Text
MimeBodyPart textoBodyPart = new MimeBodyPart();
textoBodyPart.setText(messageBody);
// Att
MimeBodyPart adjunto = new MimeBodyPart();
adjunto.attachFile("C:/hola.txt");
// Parts email
emailContenido.addBodyPart(textoBodyPart);
emailContenido.addBodyPart(adjunto);
msg.setContent(emailContenido);
Transport.send(msg);
System.out.println("Message ok");
} catch (MessagingException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}

Java mail : attach html content along with an attachment

I'm trying to send a mail with an attachment and also along with a html content.
I know how to send the html content and the attachments separately but is it possible to send the both the html and as well as the attachment together?
Here's what I've tried :
public static void sendAttachment(final String to, final String cc, final String subject, final String text,
final byte[] attachment, final String fileName) {
if (null == to) {
return;
}
try {
Properties props = getProperties();
Session session = Session.getDefaultInstance(props);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(FROM_EMPRIS));
message.setRecipients(RecipientType.TO, InternetAddress.parse(to));
if(null != cc)
message.addRecipient(RecipientType.CC, new InternetAddress(cc));
if (null != subject)
message.setSubject(subject);
BodyPart messageBodyPart1 = new MimeBodyPart();
messageBodyPart1.setText(text);
BodyPart messageBodyPart2 = new MimeBodyPart();
DataSource ds = new ByteArrayDataSource(attachment, "application/x-any");
messageBodyPart2.setDataHandler(new DataHandler(ds));
messageBodyPart2.setFileName(fileName);
Multipart multiPart = new MimeMultipart();
multiPart.addBodyPart(messageBodyPart1);
multiPart.addBodyPart(messageBodyPart2);
message.setContent(multiPart);
Transport.send(message);
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
This one sends the attachment and the setText(text) as a plaintext. Can this be changed to a html content instead of a plaintext?
Would greatly appreciate your help and thanks a lot.
Just create another mimeBodyPart with html content and setContent(htmlContent, "text/html"). Add that after your plain text body part.
Use below method and set html content in body
message.setContent(body,"text/html");
Set DataHandler for messageBodyPart1
BodyPart messageBodyPart1 = new MimeBodyPart();
messageBodyPart1.setText(text);
messageBodyPart1.setDataHandler(new DataHandler(textHtml, "text/html;charset=utf-8"));// this is to handle html

Send HTML email along with multiple file attachments?

I am trying to send an HTML email in the body of an email along with few file attachments as well. I came up with below code:
public void sendEmail(final String to, final String from, final String cc, final String subject, final String body,
final String baseDirectory, final List<String> listOfFileNames) {
for (int i = 1; i <= 3; i++) { // retrying
try {
Session session = Session.getInstance(mailProperties, null);
Multipart multipart = new MimeMultipart();
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress[] toAddress = InternetAddress.parse(to);
InternetAddress[] ccAddress = InternetAddress.parse(cc);
message.addRecipients(RecipientType.TO, toAddress);
message.addRecipients(RecipientType.CC, ccAddress);
message.setSubject(subject);
message.setContent(body, "text/html;charset=utf8");
for (String file : listOfFileNames) {
String fileLocation = baseDirectory + "/" + file;
addAttachment(multipart, fileLocation);
}
message.setContent(multipart);
Transport.send(message, toAddress);
break;
} catch (Exception ex) {
// log exception
}
}
}
// this is used for attachment
private void addAttachment(final Multipart multipart, final String filename) throws MessagingException {
DataSource source = new FileDataSource(filename);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
}
I need to have body String as part of my HTML email and have all the files attach in the same email. I am running like this as in my home directory, I have two files: abc.csv and tree.txt.
EmailTest.getInstance().sendEmail("hello#host.com", "hello#host.com", "hello#host.com",
"Test Subject (" + dateFormat.format(new Date()) + ")", content, "/export/home/david/",
Arrays.asList("abc.csv", "tree.txt"));
After I get an email, I don't see my text in the body of an email at all? And second thing is file attachment name is coming as /export/home/david/abc.csv and /export/home/david/tree.txt?
Is anything wrong I am doing? One thing I see wrong as I am calling setContent method twice with different parameters?
First you need to add the text as an own BodyPart. Next your MimeMultipart needs to be set to the type related so you can have both, HTML-Text and some attachements. Then it should work to have both, attachements and text.
And the filename you pass to messageBodyPart.setFileName(filename) is the filename you see in the attachment name. So just leave out the path and you should just see abc.csv and tree.txt
public void sendEmail(final String to, final String from, final String cc, final String subject, final String body,
final String baseDirectory, final List<String> listOfFileNames) {
for (int i = 1; i <= 3; i++) { // retrying
try {
Session session = Session.getInstance(mailProperties, null);
Multipart multipart = new MimeMultipart("related");
MimeBodyPart bodyPart= new MimeBodyPart();
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress[] toAddress = InternetAddress.parse(to);
InternetAddress[] ccAddress = InternetAddress.parse(cc);
message.addRecipients(RecipientType.TO, toAddress);
message.addRecipients(RecipientType.CC, ccAddress);
message.setSubject(subject);
bodyPart.setText(body, "UTF-8", "html");
multipart.addBodyPart(bodyPart);
for (String file : listOfFileNames) {
String fileLocation = baseDirectory + "/" + file;
addAttachment(multipart, fileLocation, file);
}
message.setContent(multipart);
Transport.send(message, toAddress);
break;
} catch (Exception ex) {
// log exception
}
}
}
// this is used for attachment
private void addAttachment(final Multipart multipart, final String filepath, final String filename) throws MessagingException {
DataSource source = new FileDataSource(filepath);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
}

Sending mail via Java API: How to send the mail even if attachment fails?

This is my code:
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(messageSubject);
message.setText(messageBody);
BodyPart messageBodyPart1 = new MimeBodyPart();
messageBodyPart1.setText(messageBody);
MimeBodyPart messageBodyPart2 = new MimeBodyPart();
String filename = attachment;
DataSource source = new FileDataSource(filename);
messageBodyPart2.setDataHandler(new DataHandler(source));
messageBodyPart2.setFileName(filename);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart1);
multipart.addBodyPart(messageBodyPart2);
message.setContent(multipart );
Transport.send(message);
} catch (MessagingException mex) {
mex.printStackTrace();
}
How can I still send the email even if mail attachment fails for some reason? ATM if attachment fails, the email is not sent, which is bad in my case.
Should I use another try/catch statement and should I have finally as well?
Im new to Java (3-4 weeks)
edit:
Changed my code to this, but didnt work
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(messageSubject);
message.setText(messageBody);
try {
BodyPart messageBodyPart1 = new MimeBodyPart();
messageBodyPart1.setText(messageBody);
MimeBodyPart messageBodyPart2 = new MimeBodyPart();
String filename = attachment;
DataSource source = new FileDataSource(filename);
messageBodyPart2.setDataHandler(new DataHandler(source));
messageBodyPart2.setFileName(filename);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart1);
multipart.addBodyPart(messageBodyPart2);
message.setContent(multipart);
} catch (Exception e) {
message.setText(messageBody2);
e.printStackTrace();
}
Transport.send(message);
} catch (MessagingException mex) {
mex.printStackTrace();
}
Yes. I would expect to be able to do (pseudo-code follows)
try {
// set up standard message
try {
// perform attachment
}
catch {
// perhaps amend your original message to indicate attachment failed
}
send();
}
catch {
// handle a complete failure here...
}
although I'd concentrate on why the attachment fails. Does that even make sense ?
You may take the approach of building/sending in two different methods, such that you don't have to clean up / modify your message in the face of a failure. That may be a cleaner approach e.g. (pseudo-code again)
try {
sendMessageWithAttachment();
}
catch {
sendMessageWithoutAttachment();
}

Categories