Couldn't prepare mail with inline image using Thymeleaf templateEngine? - spring

I am trying to send a html email with an inline-image attached using spring mvc and Thymeleaf. My code works without attaching the image. I get the html email successfully without image. But When I added the following line to my code I get the below error message.
Without this line code works and I get the email without image:
message.addInline(image.getName(), imageSource, image.getContentType());
This is the method:
public void sendUserRegisterEmail(String receiver, String receiverEmailAddress){
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
Path path = Paths.get("/assets/dist/img/dialog_tv_logo-white-01.png");
String fileName = "dialog_tv_logo-white-01.png";
String originalFileName = "dialog_tv_logo-white-01.png";
String contentType = "image/png";
byte[] content = null;
try {
content = Files.readAllBytes(path);
} catch (final IOException e) {
}
MultipartFile image = new MockMultipartFile(fileName,
originalFileName, contentType, content);
Locale locale = Locale.getDefault();
final Context ctx = new Context(locale);
ctx.setVariable("name", receiver);
ctx.setVariable("subscriptionDate", new Date());
ctx.setVariable("imageResourceName", image.getName());
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
message.setSubject(USER_REGISTER_MESSAGE_SUBJECT);
message.setTo(receiverEmailAddress);
message.setFrom(SENDER_EMAIL_ADDRESS);
final String htmlContent = emailTemplateEngine.process("email-inlineimage", ctx);
message.setText(htmlContent, true /* isHtml */);
final InputStreamSource imageSource = new ByteArrayResource(image.getBytes());
message.addInline(image.getName(), imageSource, image.getContentType());
}
};
sendEmail(preparator);
}
Following error message I get when the image prepare line is added:
org.springframework.mail.MailPreparationException: Could not prepare mail; nested exception is java.lang.IllegalStateException: Not in multipart mode - create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag if you need to set alternative texts or add inline elements or attachments.
Can any one figure out what is the issue here?

Finally able to fix the error after a lot of effort. Changing the following line fixed the issue. Create MimeMessageHelper by passing true
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);

Related

How to use MockMVC test the controller which use org.apache.commons.fileupload?

My Controller use " org.apache.commons.fileupload " realized the file UPload.
see it:
#PostMapping("/upload")
public String upload2(HttpServletRequest request) throws Exception {
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request);
boolean uploaded = false;
while (iter.hasNext() && !uploaded) {
FileItemStream item = iter.next();
if (item.isFormField()) {
item.openStream().close();
} else {
String fieldName = item.getFieldName();
if (!"file".equals(fieldName)) {
item.openStream().close();
} else {
InputStream stream = item.openStream();
// dosomething here.
uploaded = true;
}
}
}
if (uploaded) {
return "ok";
} else {
throw new BaseResponseException(HttpStatus.BAD_REQUEST, "400", "no file field or data file is empty.");
}
}
and my MockMvc code is
public void upload() throws Exception {
File file = new File("/Users/jianxiaowen/Documents/a.txt");
MockMultipartFile multipartFile = new MockMultipartFile("file", new FileInputStream(file));
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", "----WebKitFormBoundaryaDEFKSFMY18ehkjt");
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(baseUrl+"/upload")
.content(multipartFile.getBytes())
.contentType(mediaType)
.header(Origin,OriginValue)
.cookie(cookie))
.andReturn();
logResult(mvcResult);
}
my controller is right , it has successed in my web project,
but I want to test it use MvcMock, it has some mistake, see :
can someOne can help me?
"status":"400","msg":"no file field or data file is empty.","data":null
I don't know why it says my file is empty.
my English is poor, thank you very much if someone can help me.
The MockMvc can be used for integration testing for controllers using Apache Commons Fileupload too!
Import the org.apache.httpcomponents:httpmime into your pom.xml or gradle.properties
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.13</version>
</dependency>
Update the code to use MultipartEntityBuilder to build the multipart request on the client, and then serialize the entity into bytes, which is then set in the request content
public void upload() throws Exception {
File file = new File("/Users/jianxiaowen/Documents/a.txt");
String boundary = "----WebKitFormBoundaryaDEFKSFMY18ehkjt";
// create 'Content-Type' header for multipart along with boundary
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", boundary); // set boundary in the header
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
// create a multipart entity builder, and add parts (file/form data)
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
HttpEntity multipartEntity = MultipartEntityBuilder.create()
.addPart("file", new FileBody(file, ContentType.create("text/plain"), file.getName())) // add file
// .addTextBody("param1", "value1") // optionally add form data
.setBoundary(boundary) // set boundary to be used
.build();
multipartEntity.writeTo(outputStream); // or getContent() to get content stream
byte[] content = outputStream.toByteArray(); // serialize the content to bytes
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.post(baseUrl + "/upload")
.contentType(mediaType)
.content(content) // finally set the content
.header(Origin,OriginValue)
.cookie(cookie)
).andReturn();
logResult(mvcResult);
}
Can you try the below?
mockMvc.perform(
MockMvcRequestBuilders.multipart(baseUrl+"/upload")
.file(multiPartFile)
).andReturn();
Update:
You need to update the controller to handle the MultipartFile:
#PostMapping("/upload")
public String upload2(#RequestParam(name="nameOfRequestParamWhichContainsFileData")
MultipartFile uploadedFile, HttpServletRequest request) throws Exception {
//the uploaded file gets copied to uploadedFile object.
}
You need not use another library for managing file uploads. You can use the file upload capabilities provided by Spring MVC.

Send image in thymeleaf

I want to send a message via email in which the alert and image will be sent using thymeleaf, but I do not want to send it in the implementation method of sending the message, since I cannot make changes to this image in any way, can I add an image to the html code? I try to add an image to the html code, the image does not open and I can't do anything with it, I want the image to appear and I could transfer text to it
public void send(String emailTo, String subject, String message,String content) throws MessagingException, IOException {
MimeMessage mimeMessage = mailSender.createMimeMessage();
mimeMessage.setSubject(subject);
mimeMessage.setContent(content, "HTML5");
MimeMessageHelper helper;
helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(username);
helper.setTo(emailTo);
helper.setText(message,true);
// FileSystemResource file = new FileSystemResource(new File("src/main/resources/templates/image/valayev.jpg"));
// helper.addInline("valyaev", file);
mailSender.send(mimeMessage);

send mail through spring boot application

I am creating spring boot application where I have to send newly generated response string for each transaction to user as a text file attachment
so what will be the proper way to do this
any help would be appreciated
Try this below code:
#Override
public void sendMessageWithAttachment(
String to, String subject, String text, String pathToAttachment) {
// ...
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
FileSystemResource file
= new FileSystemResource(new File(pathToAttachment));
helper.addAttachment("Invoice", file);
emailSender.send(message);
// ...
}

Spring + Thymeleaf mail template - why are inline images attached to email?

I'm using spring + thymeleaf to send emails. My mail template has few images which are displayed properly in the email, however i see that unused images are attached to the bottom of the email. I have business logic in the html, which decides what images to show and what not, so sometimes some images are not used but are attached. How do i get rid of them?
Any ideas?
Here is how i load the image in html:
<img src="cid:change-password" alt="">
Here is how i send the email:
public void sendUsingTemplate(String fromEmail, String toEmail, String subject, String templateName, Map<String, Object> variables) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setSubject(subject);
final Context context = new Context(Locale.getDefault());
variables.forEach((name, value) -> context.setVariable(name, value));
String text = templateEngine.process(templateName, context);
helper.setText(text, true);
helper.setFrom(fromEmail);
helper.setTo(toEmail);
Map<String, String> inlineResources = mailTemplateResourcesProvider.getInlineResources(templateName);
inlineResources.forEach((contentId, file) -> addInlineWithoutCheckedException(helper, contentId, file));
mailSender.send(message);
} catch (Exception e) {
logger.error("Error sending mail using template", e);
}

How to get HttpServletRequest object in Spring Schedular (#Schedule)?

I am trying to send a mail using spring scheduler. In that I need HttpServletRequest object to create webContext, so that I can send mail using thyme leaf.
Anyone know the answer of this. Thanks in advance. Code is as follows,
#Async
private void sendNotification(String toField, Users user, int currentMonth)
throws Exception {
// Prepare the evaluation context
#SuppressWarnings("deprecation")
**//here i need request object**
final WebContext ctx = new WebContext(request, request.getSession()
.getServletContext(), request.getLocale());
ctx.setVariable("eagletId", user.getEagletId());
ctx.setVariable("name", user.getFirstName());
ctx.setVariable("setSentDate", new Date());
ctx.setVariable("department", user.getDepartment());
ctx.setVariable("batch", user.getBatch());
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(user.getEmail());
// create html body using thymeleaf
final String htmlContent = this.templateEngine.process("email.html",
ctx);
helper.setText(htmlContent, true);
mailSender.send(message);
}

Resources