Send attached in mail java - 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.

Related

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.

email sending with multiple attachments using MultipartFile

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);

Javamail doesn't send email with larger attachments

I want to send an email using Javamail with 2 attachments. One of them is a json file, and the other one is a txt file (logcat.txt). The logcat.txt is about 1mb in size.
It doesn't send any email if I have the addAttachment(multipart,reportPath,"logcat.txt"); in my code. If I remove addAttachment(multipart,reportPath,"logcat.txt"); it works.
When the json file gets larger, at one point about 500kb, it doesn't send either.
My code:
public synchronized void sendReport(String subject, String body, String filepath, String filename, String reportPath, String sender, String recipients){
try {
Multipart multipart = new MimeMultipart("mixed"); //try adding "mixed" here as well but it doesn't work
MimeMessage message = new MimeMessage(session);
message.setSender(new InternetAddress(sender));
message.setSubject(subject);
//body
BodyPart messageBodyPart2 = new MimeBodyPart();
messageBodyPart2.setText(body);
Log.d(TAG, "sendReport: " + reportPath);
//this prints sendReport: /storage/emulated/0/Android/data/**app package name**/files/LOG-1472631395.json
Log.d(TAG, "sendReport: " + filepath);
//sendReport: /storage/emulated/0/Android/data/**app package name**/files/logcat.txt
addAttachment(multipart,filepath,filename);
addAttachment(multipart,reportPath,"logcat.txt");
multipart.addBodyPart(messageBodyPart2);
message.setContent(multipart);
if (recipients.indexOf(',') > 0)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
else
message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
Transport.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void addAttachment(Multipart multipart, String filepath, String filename) throws MessagingException
{
DataSource source = new FileDataSource(filepath);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
}
I also use another method to send attachments but it doesn't work either:
private static void addAttachment(Multipart multipart, String filepath, String filename) throws Exception
{
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.attachFile(filepath);
mimeBodyPart.setFileName(filename);
multipart.addBodyPart(mimeBodyPart);
}
Does anyone have an idea how to fix this? Thank you in advance.
//In this list set the path from the different files you want to attach
String[] attachments;
Multipart multipart = new MimeMultipart();
//Add attachments
if(attachments != null && attachments.length > 0) {
for (String str : attachments) {
MimeBodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(str);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(source.getName());
multipart.addBodyPart(messageBodyPart);
}
}
message.setContent(multipart);
I don't have problems uploading huge files, you can try this code.
I used a private mail server of my customer to send emails, and it doesn't show any errors that I can see (because it is a public mail server). I then use Google Mail server, and this is a reply from gmail server to my email account:
Technical details of permanent failure: Google tried to deliver your
message, but it was rejected by the server for the recipient domain
mailinator.com by mail2.mailinator.com. [45.79.147.26].
The error that the other server returned was: 552 5.3.4 Message size
exceeds fixed limit
So this is because the domain mailinator.com has some message size limit so it doesn't appear. I then send things to a gmail email account and it works.

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;
}

Java send email with file in attachment

i want to send a file in attachment using java.
I have two classes, one where the file location is specified and the second class is used as utility class to send the email
So when i execute the first class it does not send the email.
First class:
public class SendFile {
private static String[] args;
public static void sendEmail(File filetosend) throws IOException, Exception{
//public static void main(String[] args) throws IOException {
final String username = "email0#gmail.com";
final String password = "password";
Properties props = new Properties();
props.put("mail.smtp.auth", true);
props.put("mail.smtp.starttls.enable", true);
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
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("email0#gmail.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("email0#gmail.com"));
message.setSubject("Attach file Test from Netbeans");
message.setText("PFA");
MimeBodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
messageBodyPart = new MimeBodyPart();
//String filetosend = ("c:\\file.txt");
DataSource source = new FileDataSource(filetosend);
System.out.println("The filetosend is ="+filetosend);
messageBodyPart.setDataHandler(new DataHandler(source));
System.out.println("The source is ="+source);
messageBodyPart.attachFile(filetosend);
System.out.println("The file name is ="+messageBodyPart.getFileName());
multipart.addBodyPart(messageBodyPart);
System.out.println("The message body part is ="+messageBodyPart);
message.setContent(multipart);
System.out.println("The message multi part is ="+multipart);
System.out.println("Sending");
Transport.send(message);
System.out.println("The message is ="+message);
System.out.println("Done");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
And the second class:
import java.io.File;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws Exception {
}
File file;
public void Test() throws IOException, Exception{
System.out.println("Sending the file...");
File filetosend = new File("c:\\file.txt");
SendFile.sendEmail(filetosend);
}
}
There is no error but the file is not sent.
Any help please, thank you
Your code is wrong. If you copied it from somewhere, the original is wrong too, or you copied it wrong. This is what you want:
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("email0#gmail.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("email0#gmail.com"));
message.setSubject("Attach file Test from Netbeans");
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("PFA");
attachmentBodyPart = new MimeBodyPart();
System.out.println("The filetosend is ="+filetosend);
System.out.println("The source is ="+source);
attachmentBodyPart.attachFile(filetosend);
System.out.println("The file name is ="+attachmentBodyPart.getFileName());
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
multipart.addBodyPart(attachmentBodyPart);
message.setContent(multipart);
System.out.println("The message multi part is ="+multipart);
System.out.println("Sending");
Transport.send(message);
Your code looks fine. In fact, I use almost the exact same code to send messages with attachments. You should probably look at whether or not you need to add authentication to the Transport and connect using the host, port, auth id, and auth pass. Also, check for any firewalls blocking messages with attachments (incredibly common issue).
If you look at this post Stack Overflow post on sending multiple attachments
You will see that nearly the same thing is done, and it gives an example on how to send the message with authentication.

Categories