Issue
I have a Spring Boot utility application that is not a web service. It exposes no RESTful/GQL (HTTP) endpoints. It consumes off a queue and does work. But I like to still make it a Spring Boot app anyways because there are so many non-web related features (dependency injection, JPA, caching, etc.).
One new thing that this utility app now needs to do is read Thymeleaf-formatted HTML templates from the file system, inject it and bind variables to it, and upload the fully templated version to S3. Hence if it reads the following vendor-abc.html
from the file system:
<html xmlns:th="https://thymeleaf.org">
<table>
<tr>
<td><h4>User Name: </h4></td>
<td><h4 th:text="${user.name}"></h4></td>
</tr>
<tr>
<td><h4>Email ID: </h4></td>
<td><h4 th:text="${user.email}"></h4></td>
</tr>
</table>
</html>
And its bindings are as follows:
@Data // lombok to generate ctors/getters/setters/etc.
public class User {
private String name;
private String email;
}
User user = new User("Jerry Jingleheimer", "[email protected]");
Then the following vendor-abc-output.html
file will be uploaded to AWS S3:
<html xmlns:th="https://thymeleaf.org">
<table>
<tr>
<td><h4>User Name: </h4></td>
<td><h4>Jerry Jingleheimer</h4></td>
</tr>
<tr>
<td><h4>Email ID: </h4></td>
<td><h4>[email protected]</h4></td>
</tr>
</table>
</html>
All Thymeleaf examples that I can find involve @Controller
-annotated classes whose methods get injected with @Model
like so:
@GetMapping("/hello")
public String mainWithParam(
@RequestParam(name = "name", required = false, defaultValue = "")
String name, Model model) {
model.addAttribute("message", name);
return "welcome"; //view
}
But here, I will have a single @Service
-annotated class that has to do all this work (no @Model
):
@Service
public class S3FileTemplater {
public void templatizeAndUpload(File htmlTemplate, User user) {
// fetch all the Thymelead-templated code out of the file
String htmlContent = Files.readString(Paths.get(htmlTemplate));
// how to inject 'user' into 'htmlContent' via Thymeleaf?
String finalContentWithUser = ???
// upload to S3
s3Client.upload(finalContentWithUser);
}
}
What do I have to do so that the file gets templated by Thymeleaf properly?
Solution
You can use SpringTemplateEngine class to process your templates, set appropriate Context and send it to your AWS S3.
Here some code example:
@Autowired
private final SpringTemplateEngine templateEngine;
public String prepareTemplates(String username, String email) {
Map<String, Object> params = new HashMap<>();
params.put("username", username);
params.put("email", email);
Context context = new Context();
context.setVariables(params);
return templateEngine.process("template.html", context);
}
Here reference link for further details.
Answered By - Aleson
Answer Checked By - Willingham (JavaFixing Volunteer)