thymeleaf / thymeleaf-spring

Thymeleaf integration module for Spring
http://www.thymeleaf.org
Apache License 2.0
435 stars 157 forks source link

Can't add Jackson Modules to ObjectMapper used in JacksonStandardJavaScriptSerializer #311

Open alexrsmith-FS opened 1 year ago

alexrsmith-FS commented 1 year ago

I'm using Thymeleaf 3.0.15 with Spring Boot 2.7 which includes JPA and Hibernate.

I ran into this problem when attempting to add support for serialization of HibernateProxy objects using the jackson.datatype.Hibernate5Module. I should have been able to declare this as a @Bean on some @Configuration, then Jackson's AutoConfiguration would have picked this up. But I discovered that Thymeleaf itself instantiates it's own ObjectMapper when it serializes. It does this at org.thymeleaf.standard.serializer.StandardJavaScriptSerializer.JacksonStandardJavaScriptSerializer.

This makes it so that Jackon's AutoConfiguration is completely bypassed. In my opinion, because this is a sping specific thymeleaf module. The ObjectMapper that is used should default to looking for a @Bean, then instantiate one for itself it a @Bean has not been defined.

dstrawson commented 1 year ago

I've run into exactly the same issue - in our case we are using Joda time, and on upgrading to Spring Boot 2.7.8 we are getting the helpful error message that we should install Joda time support for ObjectMapper, ... but of course it is installed, it seems that Thymeleaf team are not supporting it. Again its because the ObjectMapper is private and inaccessible.

alexrsmith-FS commented 1 year ago

@dstrawson

You're likely completely out of luck for attempting to serialize your Joda Time objects directly to JS in thymeleaf. Here's some options I can thinking of.

  1. Don't serialize your Joda Time object into js. If you can use it on your page without attaching it to a js object then you might be able to get away with ignoring the issue.
  2. If you really need it to be a JS object you're options are, convert it to Java Time before returning from the controller endpoint. Or query for that data point outside of the thymeleaf architecture using a @RestController. So you'd need to write up an endpoint in your js that executes on page load.
  3. Last idea I don't have a solution for is to intercept Thymeleaf's process after the return from your controllers. Then you can parse the Thymeleaf Model object and check for any Joda Time and convert them to something that can be serialized. An important note on this option is that I don't know how to do it or if it's possible. I can't find anything useful online on how to go about it.

Good luck!