Using Spring Boot and Thymeleaf outside of HTTP/web/controllers

Viewed 24

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", "jj@example.com");

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>jj@example.com</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?

1 Answers

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.

Related