email sending with multiple attachments using MultipartFile - java

I am using MultipartFile to send an email with multiple attachments. my code is working fine but I am storing each file in my project then I am attaching. I don't want to store that file anywhere instead I want the file directly send to the recipients.
My code is,
Controller:
#RequestMapping(value="/sendEmailAttachment",method=RequestMethod.POST)
public #ResponseBody Response sendEmail(#RequestParam("file") MultipartFile[] file,#ModelAttribute Email email) {
SendEmail mail = new SendEmail();
return mail.sendEmail(email,file);
}
Service:
public Response sendEmail(Email email,MultipartFile[] attachFiles) {
username = email.getUsername();
password = email.getPassword();
switch (email.getDomain()) {
case "1and1.com":
host = "smtp.1and1.com";
break;
case "gmail.com":
host = "smtp.gmail.com";
break;
case "yahoo.com":
host = "smtp.mail.yahoo.com";
break;
case "rediffmail.com":
host = "smtp.rediffmail.com";
break;
default:
host = "smtp.1and1.com";
username="support#gmail.com";
password="************";
break;
}
props.put("mail.smtp.host", host);
Response response = new Response();
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
// Create a default MimeMessage object.
Message message = new MimeMessage(session);
InternetAddress[] myToList = InternetAddress.parse(email.getTo());
InternetAddress[] myBccList = InternetAddress.parse(email.getBcc());
InternetAddress[] myCcList = InternetAddress.parse(email.getCc());
// Set From: header field of the header.
message.setFrom(new InternetAddress(email.getUsername()));
// Set To: header field of the header.
message.setRecipients(Message.RecipientType.TO,myToList);
message.setRecipients(Message.RecipientType.BCC, myBccList);
message.setRecipients(Message.RecipientType.CC, myCcList);
// Set Subject: header field
message.setSubject(email.getSubject());
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Now set the actual message
messageBodyPart.setContent(email.getBody(), "text/html");
// Create a multipar message
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
if(attachFiles != null && attachFiles.length > 0){
for (MultipartFile filePath : attachFiles) {
MimeBodyPart attachPart = new MimeBodyPart();
try {
filePath.transferTo(new File(filePath.getOriginalFilename()).getAbsoluteFile());
attachPart.attachFile(filePath.getOriginalFilename());
} catch (IOException ex) {
ex.printStackTrace();
}
multipart.addBodyPart(attachPart);
}
}
// Send the complete message parts
message.setContent(multipart);
// Transport.send(message, message.getAllRecipients());
Transport.send(message);
response.setStatus(200);
response.setMessage("Sent Email Successfully");
} catch (MessagingException e) {
response.setStatus(-1);
response.setMessage(""+e);
response.setObject(e);
e.printStackTrace();
}
return response;
}
Here I have witten like,
filePath.transferTo(new File(filePath.getOriginalFilename()).getAbsoluteFile());
attachPart.attachFile(filePath.getOriginalFilename());
I dont want to transfer/save file into the project and attach, I want to send the file directly. any help will appreciated.

Try this:
attachPart.setContent(filePath.getBytes(), filePath.getContentType());
attachPart.setFileName(filePath.getOriginalFilename());
attachPart.setDisposition(Part.ATTACHMENT);

In my case, the answer of #Bill Shannon give me the error "java.io.IOException: “text/plain” DataContentHandler requires String object, was given object of type class [B"
I modified the code like this :
DataSource ds = new ByteArrayDataSource(filePath.getBytes(), filePath.getContentType());
attachPart.setDataHandler(new DataHandler(ds));
attachPart.setFileName(filePath.getOriginalFilename());
attachPart.setDisposition(Part.ATTACHMENT);

If you are using Spring, then you can use JavaMailSenderImpl and MimeMessageHelper:
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
MimeMessage mailMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mailMessage, true);
helper.addAttachment("fileName", filePath);
mailSender.send(mailMessage);

List<MultipartFile> attachments = /* this will be input for multiple files */
Multipart multipart = new MimeMultipart();
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(/* email content */, "text/html");
multipart.addBodyPart(mimeBodyPart);
for(int i = 0 ; i < attachments.size() ; i++) {
mimeBodyPart = new MimeBodyPart();
DataSource source = new ByteArrayDataSource(attachments.get(i).getBytes(), attachments.get(i).getContentType());
mimeBodyPart.setDataHandler(new DataHandler(source));
mimeBodyPart.setFileName(attachments.get(i).getOriginalFilename());
multipart.addBodyPart(mimeBodyPart);
}
email.setContent(multipart);

Related

Send attached in mail java

Here in this it works perfectly fine but instead of using the recieved file I have use file path
How can I do that
I though converting it into input stream would do some good but there is no constructor with input stream
Please let me know
Thanks in advance
#RequestMapping("/SendMail")
public String mail(#RequestParam("prescription") MultipartFile prescription,#RequestParam("email") String email,HttpSession session) {
try {
customer ct=custServ.customerExists(email);
InputStream in = prescription.getInputStream();
String filename=prescription.getName();
if(ct!=null){
final String SEmail="email#gmail.com";
final String SPass="passowrd";
final String REmail=email;
final String Sub="Your prescription is here!";
//mail send Code
Properties props=new Properties();
props.put("mail.smtp.host","smtp.gmail.com");
props.put("mail.smtp.socketFactory.port","465");
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth","true");
props.put("mail.smtp.port","465");
Session ses=Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(SEmail,SPass);
}
}
);
Message message=new MimeMessage(ses);
message.setFrom(new InternetAddress(SEmail));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(REmail));
message.setSubject(Sub);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("This is your prescription here");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
// File filep=new File(prescription);
DataSource source = new FileDataSource("C:\\Users\\Narci\\Desktop\\frontend\\Myqr3.jpg");
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
Transport.send(message);
session.setAttribute("msg","Mail Sent successfully.");
}
else{
session.setAttribute("msg", "Wrong Emial ID");
}
return "Doctor";
}
catch(Exception e) {
e.printStackTrace();
return "Error";
}
} ```
This is kind of a shot in the dark because I don't believe I truly understand the question. If the question is; How can I use a File instead of a MultipartFile and obtain an InputStream then the answer would be to use an existing library like Files.newInputStream with a Path as the parameter.
Path path = Paths.get("path", "to", "my", "file");
try (InputStream input = Files.newInputStream(path)) {
}
From this other Stack Overflow answer (this answer is posted as a community wiki) you can get in your front-end the file object and convert it into a base64 object as follows:
const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
async function Main() {
const file = document.querySelector('#myfile').files[0];
console.log(await toBase64(file));
}
Main();
Then, with this Base64 object you could send it to the backend with a PUT request to then attach it to the email following Gmail API instructions for multipart upload.

How to put Image in mail's header(Spring Boot)?

I am developing an app where I need to set image in a header and footer of a mail. I saw method setHeader(String header-name, String header_value) but when I put into it a path to my image I don't get anything.
This is my code:
public static void send(String host, String port,
final String userName, final String password, String toAddress,
String subject, String htmlBody,
Map<String, String> mapInlineImages)
throws AddressException, MessagingException {
// sets SMTP server properties
Properties properties = new Properties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.user", userName);
properties.put("mail.password", password);
// creates a new session with an authenticator
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
};
Session session = Session.getInstance(properties, auth);
// creates a new e-mail message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(userName));
InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
msg.setRecipients(Message.RecipientType.TO, toAddresses);
msg.setSubject(subject);
msg.setSentDate(new Date());
msg.setHeader("image1", "D:\\broki\\src\\main\\resources\\imageHeader.jpg");
// creates message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(htmlBody, "text/html");
// creates multi-part
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// adds inline image attachments
if (mapInlineImages != null && mapInlineImages.size() > 0) {
Set<String> setImageID = mapInlineImages.keySet();
for (String contentId : setImageID) {
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.setHeader("Content-ID", "<" + contentId + ">");
imagePart.setDisposition(MimeBodyPart.INLINE);
String imageFilePath = mapInlineImages.get(contentId);
try {
imagePart.attachFile(imageFilePath);
} catch (IOException ex) {
ex.printStackTrace();
}
multipart.addBodyPart(imagePart);
}
}
msg.setContent(multipart);
Transport.send(msg);
}
}
As you can see in part
msg.setHeader("image1", "D:\\broki\\src\\main\\resources\\imageHeader.jpg")
I put some key and value which is path to my Image which I want to set into header. But nothing happens. Can someone help me?
The word "header" in a MIME message refers to a section of the message that has "key: value" fields. This section is called "header" because it's transmitted before the "body" content of the message. The headers are for things like "Date", "Subject", "Content-Type".
The word "header" does not refer to a graphical header that would be visible on the screen or when printed. To add this type of a header, you have to modify the content of the message. In your program, that's stored in the htmlBody variable.
I don't think you can simply modify htmlBody to add a header to it, without knowing how it is structured. In the general case, the page header has to be incorporated in the HTML message design from the start.

getting syntax error in property.setProperty("mail.smtp.host",host);

I am getting the syntax for the below line while trying to send the mail through SMTP .I tried in google but didnt get any relevant answer.
property.setProperty("mail.smtp.host",host);
CODE:
public class SendMail {
//Recipient Mail id
String to = "Receiver Mail ID";
//Sender Mail Id
String from = "Sender Mail ID";
//Sending email from the localhost
String host = "localhost";
//Get System Properties
Properties property = System.getProperties();
//Setup the mail server
property.setProperty("mail.smtp.host",host);
property.setProperty("mail.smtp.port" , "465");
//property.put("mail.smtp.auth", "true");
//Get the default session object
Session session = Session.getDefaultInstance(property);
try
{
//Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
//Set From: header field of the header
message.setFrom(new InternetAddress(from));
//Set To : header field of the header
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
//Set Subject : header field
message.setSubject("Automation Testing Report");
//Create the Message part
BodyPart messageBodypart = new MimeBodyPart();
//Enter the message in the Mail Body
messageBodypart.setText("***********Find the below for the Report****************");
//Create a Multipart Message
Multipart multipart = new MimeMultipart();
//Set Text message part
multipart.addBodyPart(messageBodypart);
//Part two is attachment
/*create the Message part*/
messageBodypart = new MimeBodyPart();
String filename = "E:\\Project\\jar\\Selenium Scripts\\Hybrid_Driven\\test-output\\emailable-report.html";
DataSource source = new FileDataSource(filename);
messageBodypart.setDataHandler(new DataHandler(source));
messageBodypart.setFileName(filename);
//set the text message part
multipart.addBodyPart(messageBodypart);
//Send the complete message part
message.setContent(multipart);
//Send message
Transport.send(message);
System.out.println("Mail has sent successfully");
}
catch(MessagingException mex)
{
mex.printStackTrace();
}
}
}
Please help me to resolve this issue.
You cannot put java code directly into a class. It needs to be within methods. The following is happily accepted by the compiler:
public class SendMail {
...
//Get System Properties
java.util.Properties property = System.getProperties();
void doSomething()
{
property.setProperty("mail.smtp.host", host);
property.setProperty("mail.smtp.port", "465");
...
}
}

How to attach a PDF in a mail using Java Mail?

public static String sendMail(
String destino,
String texto,
String asunto,
byte[] formulario,
String nombre) {
Properties properties = new Properties();
try{
Session session = Session.getInstance(properties);
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("reminder#companyname.com.ar"));
//Cargo el destino
if(destino!= null && destino.length > 0 && destino[0].length() > 0 ){
for (int i = 0; i < destino.length; i++) {
message.addRecipient(Message.RecipientType.TO,new InternetAddress(destino[i]));
}
}
//message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(asunto);
//I load the text and replace all the '&' for 'Enters' and the '#' for tabs
message.setText(texto.replaceAll("&","\n").replaceAll("#","\t"));
Transport.send(message);
return "Mensaje enviado con éxito";
}catch(Exception mex){
return mex.toString();
}
}
Hello everyone.
I was trying to figure out how can I attach the PDF sent by parameters as formulario in the code previously shown.
The company used to do the following trick for this matter but they need to change it for the one previously shown:
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(
texto.replaceAll("&", "\n").replaceAll("#", "\t"));
//msg.setText(texto.replaceAll("&","\n").replaceAll("#","\t"));
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(
new DataHandler(
(DataSource) new InputStreamDataSource(formulario,
"EDD",
"application/pdf")));
messageBodyPart.setFileName(nombre + ".pdf");
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
msg.saveChanges();
Transport transport = session.getTransport("smtp");
transport.connect(
"smtp.gmail.com",
"reminder#companyname.com.ar",
"companypassword");
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
return "Mensaje enviado con éxito";
} catch (Exception mex) {
return mex.toString();
Since you already can send emails, the adjust your code and add the following part to your code
// Create a default MimeMessage object.
Message message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
// Set Subject: header field
message.setSubject("Testing Subject");
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Now set the actual message
messageBodyPart.setText("This is message body");
// Create a multipar message
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
String filename = "/home/file.pdf";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Send the complete message parts
message.setContent(multipart);
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
original code taken from here
Is formulario a byte array in both cases? If so, just rewrite the first block of code to construct the message using the technique in the second block of code. Or replace InputStreamDataSource with ByteArrayDataSource in the new version.
The sending email with attachment is similar to sending email but here the additional functionality is with message sending a file or document by making use of MimeBodyPart, BodyPart classes.
The process for sending mail with attachment involves session object, MimeBody, MultiPart objects. Here the MimeBody is used to set the text message and it is carried by MultiPart object. Because of MultiPart object here sending attachment.
try {
// Create a default MimeMessage object.
Message message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
// Set Subject: header field
message.setSubject("Attachment");
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Now set the actual message
messageBodyPart.setText("Please find the attachment below");
// Create a multipar message
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
String filename = "D:/test.PDF";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Send the complete message parts
message.setContent(multipart);
// Send message
Transport.send(message);
System.out.println("Email Sent Successfully !!");
} catch (MessagingException e) {
throw new RuntimeException(e);
}

Amazon SES custom header List-Unsubscribe isn't working

I'm tryin to add the "List-Unsubscribe" header in my sent emails (through amazon ses) but when i see the received email there's no such header in it. I need it to reduce the number of spam complaints and to improve deliverability and reputation.
SendEmailRequest sendEmailRequest = new SendEmailRequest();
sendEmailRequest.putCustomRequestHeader(UNSUBSCRIBE_HEADER, unsuscribeURL);
PS: Using others providers such as Mandrill or Sendgrid it works, but i really need it at amazon
So... i found a workaround.
If you want to add a custom header to your message, always use a RawMessage, not a simple one.
Something like this:
SendRawEmailRequest sendRawEmailRequest = new SendRawEmailRequest();
RawMessage rawMessage = null;
rawMessage = buildSimpleRawMessage(...);
sendRawEmailRequest.setRawMessage(rawMessage);
private RawMessage buildSimpleRawMessage(String subject, String message, Attachment attachment) {
RawMessage rawMessage = null;
try {
// JavaMail representation of the message
Session s = Session.getInstance(new Properties(), null);
MimeMessage mimeMessage = new MimeMessage(s);
// Subject
mimeMessage.setSubject(subject);
// Add a MIME part to the message
MimeMultipart mimeBodyPart = new MimeMultipart();
BodyPart part = new MimeBodyPart();
part.setContent(message, "text/html");
mimeBodyPart.addBodyPart(part);
// Add a attachement to the message
if(attachment!=null){
part = new MimeBodyPart();
DataSource source = null;
source = new ByteArrayDataSource(attachment.getBuf(), attachment.getMimeType());
part.setDataHandler(new DataHandler(source));
part.setFileName(attachment.getFileName());
mimeBodyPart.addBodyPart(part);
}
mimeMessage.setContent(mimeBodyPart);
mimeMessage.addHeader(UNSUBSCRIBE_HEADER, unsubscribeURL);
// Create Raw message
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
mimeMessage.writeTo(outputStream);
rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
} catch (Exception e) {
logger.error("There was a problem creating mail attachment", e);
throw Throwables.propagate(e);
}
return rawMessage;
}

Categories