MimeMessageHelper Spring boot to send email - spring-boot

I am using spring boot to sent an email. Code snippet from my email service
private #Autowired JavaMailSender mailSender;
AND
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED, StandardCharsets.UTF_8.name());
helper.setTo(bo.getToEmails().parallelStream().toArray(String[]::new));
helper.setBcc(bo.getBccEmails().parallelStream().toArray(String[]::new));
helper.setCc(bo.getCcEmails().parallelStream().toArray(String[]::new));
helper.setText(htmlBody, true);
helper.setText(textBody, false);
helper.setSubject(bo.getSubject());
helper.setFrom(new InternetAddress(bo.getFromEmail(),bo.getSenderLabel()));
First I set the htmlBody and then textBody
helper.setText(htmlBody, true);
helper.setText(textBody, false);
it override htmlBody to textBody . How can I send both text and html body using org.springframework.mail.javamail.MimeMessageHelper; any update ?

You can use thymeleaf as your HTML template engine.
Sample HTML code:
MySampleHTML.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Sample Email</title>
</head>
<body>
<div th:text="${sampleText}"></div>
</body>
<html>
Sample Java Code:
public class EmailSample {
#Autowired
private JavaMailSender mailSender;
#Autowired
private TemplateEngine templateEngine; // From Thymeleaf
public void initiateEmailSend() {
String processedHTMLTemplate = this.constructHTMLTemplate();
// Start preparing the email
MimeMessagePreparator preparator = message -> {
MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED, "UTF-8");
helper.setFrom("Sample <sample#example.com>");
helper.setTo("recipient#example.com");
helper.setSubject("Sample Subject");
helper.setText(processedHTMLTemplate, true);
};
mailSender.send(preparator); //send the email
}
// Fills up the HTML file
private String constructHTMLTemplate() {
Context context = new Context();
context.setVariable("sampleText", "My text sample here");
return templateEngine.process("MySampleHTML", context);
}
}
And include thymeleaf on your pom.xml
<!-- For email HTML templating -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
NOTE: Put the MySampleHTML.html file on resources/templates/ folder for thymeleaf to see it.

instead of
helper.setText(htmlBody, true);
helper.setText(textBody, false);
Use
helper.setText(htmlBody, textBody);

Related

Template might not exist or might not be accessible by any of the configured Template Resolvers springboot

I have a microservice app built-in spring boot, the main module is working at 8080 port and the other module is working at 7070 port. At /clicker endpoint I'm trying to redirect to
the site which is located on this port but always when I'm using /clicker endpoint I can see an error like this. But when I try to get [http://192.168.254.115:7070] directly from the browser, everything is working fine so I think that's not because of the bad config in the application.properties.
Error resolving template [http://192.168.254.115:7070], template might not exist or might not be accessible by any of the configured Template Resolvers
This controller works at 8080 port.
#CrossOrigin(origins = "*")
public class MainController {
#RequestMapping("/")
public String index() {
return "redirect:/login";
}
#RequestMapping("/home")
public String home(){
return "home.html";
}
#CrossOrigin
#RequestMapping("/clicker")
public ModelAndView goToClicker(HttpServletRequest request) {
//http://localhost:7070/
//http://192.168.254.115:7070/
String url = "http://" + request.getServerName() + ":" + "7070";
return new ModelAndView(url);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" type="text/css" th:href="#{/styles/style.css}"/>
</head>
<body>
<div class = "main">
<div class = "container">
<button type="button">CLICKER</button>
</div>
</div>
</body>
</html>
And that's the controller which works at 7070 port.
#Controller
#CrossOrigin(origins = "*")
public class ClickerController {
#CrossOrigin
#RequestMapping("/")
public String index() {
return "clicker.html";
}
}

Bootsrap not working with spring boot thymeleaf pdf template

I have a problem adding bootstrap into my thymeleaf template. I want to export that template as pdf.
Bootsrap is not applied to my template. I tried webjars and static bootsrap js and css files but it doesn't work. Is there any other way that i can do? These are webjars links that I have added inside html;
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" th:href="#{webjars/bootstrap/css/bootstrap.min.css}" type="text/css"/>
<script th:src="#{webjars/bootstrap/js/bootstrap.min.js}"></script>
<script th:src="#{webjars/jquery/jquery.min.js}"></script>
</head>
This is java code;
public byte[] getReportByTestId(Long testId, String templateName) throws IOException, DocumentException {
Optional<Test> test = testRepository.findById(testId);
if (test.isPresent()) {
Test _test = test.get();
ObjectMapper oMapper = new ObjectMapper();
Map map = oMapper.convertValue(_test, Map.class);
Context context = new Context();
context.setVariables(map);
String htmlContentToRender = templateEngine.process(templateName, context);
String xHtml = xhtmlConvert(htmlContentToRender);
ITextRenderer renderer = new ITextRenderer();
String baseUrl = FileSystems
.getDefault()
.getPath("src", "main", "resources", "templates")
.toUri()
.toURL()
.toString();
renderer.setDocumentFromString(xHtml, baseUrl);
renderer.layout();
ByteOutputStream outputStream = new ByteOutputStream();
renderer.createPDF(outputStream);
byte[] pdfAsBytes = outputStream.getBytes();
outputStream.close();
return pdfAsBytes;
}
return null;
}
private String xhtmlConvert(String html) throws UnsupportedEncodingException {
Tidy tidy = new Tidy();
tidy.setInputEncoding("UTF-8");
tidy.setOutputEncoding("UTF-8");
tidy.setXHTML(true);
ByteArrayInputStream inputStream = new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
tidy.parseDOM(inputStream, outputStream);
return outputStream.toString("UTF-8");
}
When I add like this;
<script th:src="#{../static/vendor/bootstrap5/bootstrap.min.js}"></script>
It partially works. Only colors are applied.
Thanks for any help.

spring-boot-2.0.6 freemarker mvc View print request model values twice

I am using freemarker view with spring-boot-2.0.6.RELEASE,
But my ftl view print request model value twice in HTML like "${errorTitle}" -> "PG ErrorPGError" .
If anybody has a solution, please let me know the way.
I am struggling with these problems for 3 days.
[freemarker configuration bean]
#Bean
public FreeMarkerConfigurer freemarkerConfig()throws IOException, TemplateException {
final FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
freeMarkerConfigurer.setTemplateLoaderPath("classpath:/WEB-INF/view/");
Properties settings = new Properties();
settings.setProperty(
freemarker.template.Configuration.TEMPLATE_EXCEPTION_HANDLER_KEY, "rethrow");
freeMarkerConfigurer.setFreemarkerSettings(settings);
freeMarkerConfigurer.setDefaultEncoding("UTF-8");
return freeMarkerConfigurer;
}
[/paygate/error.ftl]
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Error Page</title>
</head>
<body>
<h1>${errorTitle}</h1>
<p>${errorMessage}</p>
</body>
</html>
[pom.xml]
:::
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
:::
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
#CrossOrigin
#SkipSessionCheck
#GetMapping("/error)
public ModelAndView errorView(#RequestParam("errorMessage") String errorMessage) throws ResultCodeException {
logger.error(AppUtil.excetionToString(e)) ;
ModelAndView model = new ModelAndView();
model.addObject("errorTitle", "PG Error") ;
model.addObject("errorMessage", errorMessage) ;
model.setViewName("paygate/error");
return model ;
}

JavaMail API - Send Emoji/Smiley with Freemarker Template?

I developed rest API in spring.
I have to send invitation mail to user with Emoji.
I developed .ftl and .java configuration file is as follows:
invitation.ftl
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
//Content
</body>
</html>
webAppConfi.java
#Bean
public FreeMarkerConfigurationFactoryBean freeMarkerConfigurationFactoryBean() {
FreeMarkerConfigurationFactoryBean freeMarkerConfigurationFactoryBean = new FreeMarkerConfigurationFactoryBean();
freeMarkerConfigurationFactoryBean
.setTemplateLoaderPath("/WEB-INF/templates/mail/");
freeMarkerConfigurationFactoryBean.setDefaultEncoding("UTF-8");
return freeMarkerConfigurationFactoryBean;
}
sendMail.java
MimeMessage message = null;
MimeMessageHelper objHelper = null;
String strBody = null;
try {
strBody = FreeMarkerTemplateUtils.processTemplateIntoString(
freemarkerMailConfiguration.getTemplate(templetName),
templateProp);
message = this.mailSender.createMimeMessage();
objHelper = new MimeMessageHelper(message, true);
objHelper.setTo(to);
objHelper.setText(strBody, true);
objHelper.setSubject(subject);
mailSender.send(message);
}
finally{}
I get the string like that from iPhone \ud83d\ude14\ud83d\ude17.
So how could i send this emoji value to email body part?
Thank you!

Jersey - Freemarker - use custom ViewProcessor

My template is rendered but without the freemarker treatments.
the output is
<html>
<body>
<h1>Welcome ${user}</h1>
</body>
</html>
The variable user has not been replaced by its value.
So I'm not sure Jersey know something about my custom ViewProcessor. How can I say explicitly to Jersey that I want to use the Freemarker ViewProcessor.
I have seen the following sample but it doesn't help
http://search.maven.org/#browse%7C-1697896452
To sum up I have :
in my pom.xml
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-freemarker</artifactId>
<version>1.12</version>
</dependency>
in my JerseyServletModule
Map<String, String> params = new HashMap<String, String>();
params.put("com.sun.jersey.freemarker.templateBasePath", "freemarker");
serve("/*").with(GuiceContainer.class, params);
in my TestResource
#Path("/test")
#GET
#Produces("text/html")
public Viewable getMytestView() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("user", "Peter");
return new Viewable("/test.ftl", map);
}
in my src/main/resources/freemarker/test.ftl
<html>
<body>
<h1>Welcome ${user}</h1>
</body>
</html>
Thanks in advance for your help.
Ok it works now. Sorry, it's certainly a cache problem.

Resources