thymeleaf-spring icon indicating copy to clipboard operation
thymeleaf-spring copied to clipboard

SpringTemplateEngine overwrites any set MessageResolvers

Open paulcappadona opened this issue 4 years ago • 1 comments

Thymeleaf 3.0.11 (Spring 3/4/5)

When creating a SpringTemplateEngine and setting a message resolver as per below

	@Bean
	public SpringTemplateEngine thymeleafTemplateEngine() {
	    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
	    templateEngine.setTemplateResolver(templateResolver);
	    templateEngine.setMessageResolver(messageResolver);
	    return templateEngine;
	}

The template engine never invokes the supplied message resolver. This is due to the SpringTemplateEngine.initializeSpecific() not checking for any configured message resolvers and running through an init process that will always apply either a SpringMessageResolver or StandardMessageResolver.

    @Override
    protected final void initializeSpecific() {

        // First of all, give the opportunity to subclasses to apply their own configurations
        initializeSpringSpecific();

        // Once the subclasses have had their opportunity, compute configurations belonging to SpringTemplateEngine
        super.initializeSpecific();
        	
        final MessageSource messageSource =
                this.templateEngineMessageSource == null ? this.messageSource : this.templateEngineMessageSource;

        final IMessageResolver messageResolver;
        if (messageSource != null) {
            final SpringMessageResolver springMessageResolver = new SpringMessageResolver();
            springMessageResolver.setMessageSource(messageSource);
            messageResolver = springMessageResolver;
        } else {
            messageResolver = new StandardMessageResolver();
        }

        super.setMessageResolver(messageResolver);

    }

I couldn't find any workaround. Modifying the source to include a check in the above method to return should a message resolver already be set resulted in my MessageResolver being invoked as expected.

paulcappadona avatar Jul 02 '20 04:07 paulcappadona

You might fix it this way:

  1. do not set the messageResolver in thymeleafTemplateEngine() (see official docs):
@Bean
	public SpringTemplateEngine thymeleafTemplateEngine() {
	    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
	    templateEngine.setTemplateResolver(templateResolver);
	    return templateEngine;
	}
  1. do not create a new TemplateEngine when creating a ViewResolver:

WRONG (shown in the docs)

    @Bean
    public ThymeleafViewResolver viewResolver(){
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        return viewResolver;
    }

CORRECT

    @Bean
    public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine){
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine);
        return viewResolver;
    }
  1. Define a MessageSource bean somewhere:
	@Bean
	public MessageSource messageSource() {
		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
		...
		return messageSource;
	}

xtianus avatar Oct 09 '20 08:10 xtianus