I have a minimalistic thymeleaf config in my spring boot app, which is used just to render the html into PDF file.
I am upgrading to spring boot 3, and need to upgrade thymeleaf from 3.0 to 3.1
Here is my old code before upgrade to spring boot 3, the main difference is the construction of WebContext
. In thymeleaf 3.0 I was building it based on servlet request/response, but in thymeleaf 3.1, we are building it from WebExchange object
Controller for Thymeleaf 3.0
override fun previewDataController(
request: HttpServletRequest,
response: HttpServletResponse,
objId: UUID,
): ResponseEntity<ByteArray> {
val context = WebContext(request, response, request.servletContext)
val pdfData = someService.previewData(context, objId)
...
}
And the upgrade to Thymeleaf 3.1
override fun previewDataController(
webExchange: IWebExchange,
objId: UUID,
): ResponseEntity<ByteArray> {
val context = WebContext(webExchange, webExchange.locale)
val pdfData = someService.previewData(context, objId)
...
}
Here is the failing code
@Autowired
val templateEngine: TemplateEngine
...
fun someMethod(context: WebContext) {
val htmlString = templateEngine.process("resources/template", context)
...
}
I have the object object
in the context, and I can see in debug that this property is not null
Here is the template:
<body>
<p>Name <span th:text="${object.name}">#</span></p>
</body>
But my unit test is failing, stating that object
from the template is null. Here is the stack trace:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'name' cannot be found on null
Questions:
- Is this the correct way to build the IWebExchange object? Will it be bound by spring?
- Am I missing any configuration for the new 3.1 version?
- Can it be a problem of the test context config?
Thanks!
CodePudding user response:
Things have changed considerably for Thymeleaf. Mostly because the JavaEE
and JakartaEE
support it provides, so things needed to be abstracted away. Simply creating a WebExchange
is a bit more involved now.
What you should be able to do (Java code which you can probably convert).
public class ThymeleafHelper {
public static WebContext createContext(HttpServletRequest req, HttpServletResponse res) {
var application = JakartaServletWebApplication.buildApplication(req.getServletContext());
var exchange application.buildExchange(req, res);
return new WebContext(exchange);
}
}
You should be able to call this (and convert it to Kotlin) to create the WebContext
you will need.