-
Notifications
You must be signed in to change notification settings - Fork 41.5k
Description
The new support for Thymeleaf + Spring WebFlux auto-configuration (#8124) works great, but there is one point in ThymeleafAutoConfiguration
where now this is done:
@Bean
@ConditionalOnMissingBean(name = "thymeleafReactiveViewResolver")
public ThymeleafReactiveViewResolver thymeleafViewResolver(
ISpringWebFluxTemplateEngine templateEngine) {
ThymeleafReactiveViewResolver resolver = new ThymeleafReactiveViewResolver();
...
resolver.setSupportedMediaTypes(
this.properties.getReactive().getMediaTypes());
...
return resolver;
}
So the Thymeleaf auto-configuration mechanism always overwrites the supported media types with whatever comes from the ThymeleafProperties.Reactive
object. But in that class, such supported media types are initialised like this:
private List<MediaType> mediaTypes = new ArrayList<>(
Collections.singletonList(MediaType.TEXT_HTML));
So unless specifically configured by the user, text/html
will always be the only media type that Thymeleaf is allowed to run for.
This was fine until Thymeleaf 3.0.3. But Thymeleaf 3.0.4 introduced support for text/event-stream
in Thymeleaf's WebFlux support, and now Thymeleaf 3.0.6 introduces a series of improvements to the way content negotiation is integrated into Thymeleaf's view resolution (and linked with template resolution and template modes themselves) that allow Thymeleaf to be more easily used for processing dynamic CSS
, JAVASCRIPT
or XML
templates with the same configuration setup. Ideally, with no additional configuration at all.
In fact, the list of supported media types at ThymeleafReactiveViewResolver
has grown quite a lot in 3.0.6:
private static final List<MediaType> SUPPORTED_MEDIA_TYPES =
Arrays.asList(new MediaType[] {
MediaType.TEXT_HTML, MediaType.APPLICATION_XHTML_XML, // HTML
MediaType.APPLICATION_XML, MediaType.TEXT_XML, // XML
MediaType.APPLICATION_RSS_XML, // RSS
MediaType.APPLICATION_ATOM_XML, // ATOM
new MediaType("application", "javascript"), // JAVASCRIPT
new MediaType("application", "ecmascript"), //
new MediaType("text", "javascript"), //
new MediaType("text", "ecmascript"), //
MediaType.APPLICATION_JSON, // JSON
new MediaType("text", "css"), // CSS
MediaType.TEXT_PLAIN, // TEXT
MediaType.TEXT_EVENT_STREAM}); // SERVER-SENT EVENTS (SSE)
I'm not a huge expert in how WebFlux's content negotiation mechanism works, so I might be missing some reason why giving direct support for this in Spring Boot's auto-configuration would be a bad idea… but if not, it would be great if ThymeleafAutoConfiguration
and ThymeleafProperties.Reactive
didn't overwrite all these values.
This could be easily achieved by making the default value for mediaTypes
in ThymeleafProperties.Reactive
be null
, and also making this bit of configuration optional at ThymeleafAutoConfiguration
, like:
@Bean
@ConditionalOnMissingBean(name = "thymeleafReactiveViewResolver")
public ThymeleafReactiveViewResolver thymeleafViewResolver(
ISpringWebFluxTemplateEngine templateEngine) {
ThymeleafReactiveViewResolver resolver = new ThymeleafReactiveViewResolver();
...
final List<MediaType> mediaTypes = this.properties.getReactive().getMediaTypes();
if (mediaTypes != null) {
resolver.setSupportedMediaTypes(mediaTypes);
}
...
return resolver;
}
Finally, note that this does not affect the non-reactive version, because in such case the equivalent contentType
property works as a sort of default value for the HTTP header, instead of a comprehensive list of all the media types for which Thymeleaf will be actually allowed to run for once content negotiation takes place.