Thymeleaf Spring JSF

Asked

Viewed 635 times

1

I’m trying to do the internationalization of templat using

  • Thymeleaf 3.0
  • Spring 4.2.3
  • JSF 2.2

Which is sent along with an email.

#{i18N.descriptionPortal}

When you print in the email html it looks like this

??i18N.descriptionPortal_pt_BR??

the Thymeleaf do not know of the i18n that works in JSF pages, some hint of how to parametrize it?

Configuration for i18n and Thymeleaf

@Configuration(value = "webapp")
@EnableWebMvc
@EnableTransactionManagement
@EnableScheduling
@ApplicationScoped
public class AppInitializer extends WebMvcConfigurerAdapter implements WebApplicationInitializer, ApplicationContextAware
{


    private ApplicationContext          applicationContext;

    @Override
    public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer)
    {
        configurer.enable();
    }

    @Override
    public void onStartup(final ServletContext servletContext) throws ServletException
    {
        final AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(Config.class);
        //definido o listener do spring para o contexto
        servletContext.addListener(new RequestContextListener());
        servletContext.addListener(new ContextLoaderListener(ctx));
        ctx.setServletContext(servletContext);
    }


    @Bean
    @Autowired
    public ViewResolver viewResolver(@Qualifier("templateEngine") final TemplateEngine templateEngine)
    {
        final ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine);
        resolver.setCharacterEncoding("UTF-8");
        return resolver;
    }


    @Bean(name = "templateEngine")
    public TemplateEngine templateEngine() throws Exception
    {
        final SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setEnableSpringELCompiler(true);
        engine.setTemplateResolver(templateResolver());
        engine.afterPropertiesSet();
        return engine;
    }

    private ITemplateResolver templateResolver()
    {
        final SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setApplicationContext(applicationContext);
        resolver.setPrefix("/WEB-INF/classes/mail/");
        resolver.setTemplateMode(TemplateMode.HTML);
        return resolver;
    }

    @Bean(name = "msg")
    public MessageSource messageSource()
    {
        final ResourceBundleMessageSource message = new ResourceBundleMessageSource();
        message.setBasenames("messages/messages", "messages/build");
        message.setDefaultEncoding("UTF-8");
        message.setUseCodeAsDefaultMessage(true);
        return message;
    }

    @Bean
    public LocaleResolver localeResolver()
    {
        final SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(new Locale("pt", "BR"));
        return localeResolver;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        final LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        lci.setParamName("msg");
        return lci;
    }   
}

These are the forms I tried to use in the template, I’ve made several settings and nothing.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:th="http://www.thymeleaf.org" th:with="lang=${#locale.language}" th:lang="${msg}">
<body>
    <table class="tableCenter">
        <tr>
            <th colspan="2">
                <h2>
                    <span th:utext="#{msg.descriptionPortal}" />
                    <span th:utext="#{descriptionPortal}" />
                </h2>
            </th>
        </tr>
        .
        .
        .

This is the result in the email received

??msg.descriptionPortal_pt_BR?? ?? descriptionPortal_pt_BR??

This is the error when I try to use the i18n key in . xhtml

GRAVE: Error Rendering View[/mod/home.xhtml]
javax.el.ELException: /mod/home.xhtml: Property 'descriptionPortal' not found on type org.springframework.context.support.ResourceBundleMessageSource
    at com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:88)
    at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
    at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:82)
    at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:72)
    at org.primefaces.component.outputpanel.OutputPanelRenderer.encodeMarkup(OutputPanelRenderer.java:65)
    at org.primefaces.component.outputpanel.OutputPanelRenderer.encodeEnd(OutputPanelRenderer.java:41)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
    at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:89)
    at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:72)
    at org.primefaces.component.outputpanel.OutputPanelRenderer.encodeMarkup(OutputPanelRenderer.java:65)
    at org.primefaces.component.outputpanel.OutputPanelRenderer.encodeEnd(OutputPanelRenderer.java:41)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1903)
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1896)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1899)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1899)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:451)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at com.sys.filters.SysFilterLogin.executeRequest(SysFilterLogin.java:194)
    at com.sys.filters.SysFilterLogin.processSession(SysFilterLogin.java:142)
    at com.sys.filters.SysFilterLogin.doFilter(SysFilterLogin.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at com.sys.filters.SysFilterAllRequest.doFilter(SysFilterAllRequest.java:55)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at com.sys.filters.SysCharacterEncodingFilter.doFilter(SysCharacterEncodingFilter.java:39)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

I’ve done many other configurations but practically always arrive at the same result

2 answers

1

This return of Themeleaf is that it did not find the text in pt_BR for the variable "descriptionPortal".

Take a look at this answer Using i18n

You basically need to create a messages_pt_BR.properties file within Resources/i18n/ and have the variable there

descriptionPortal = Descrição do Portal em português

Add the parameter to the tag you are using, for example:

<p th:text="${descriptionPortal}"></p>
  • I looked at what you suggested, tried to adjust compliant tips and nothing, updated with parts of the source and error I’m having, the question.

  • Inside the messages/messages folder, is there the messages_pt_BR file? Did you test with messages_en_US.properties? You have to see which site Thymeleaf is recognizing.

  • Another thread, as you set pt_BR by default, try using the message.properties. file Your browser/ OS has locales like pt_BR?

  • Yes there are the files, messages_pt_BR.properties and messages_en_US.properties.

  • As you set with default = pt_BR, there must be message.properties

1

The whole problem was generated as follows:

  • Themeleaf injects into your source somewhere, it only reads the Messagesource interface;
  • That must have the bean messageSource
  • How JSF needs java.util.Resourcebundle
  • Creates a Singleton Resourcebundle object
  • In this case called i18n

    @Component("i18N")
    @Scope("singleton")
    public class SysResourceBundleRead extends ResourceBundle implements Serializable, MessageSource{
     ..
     ..
     ..
    }
  • See the object implementing Messagesource
  • Now in the configuration I get the object
  • @Qualifier("i18n")
    
    @Bean(name = { "messageSource"})
    @Autowired
    public MessageSource messageSource(@Qualifier("i18N") final SysResourceBundleRead resourceBundleRead)
    {
        return resourceBundleRead;
    }
    
  • So whoever uses this name uses the same object thinking it is messageSource, default

The jsf configuration integrating Spring looks like this

<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    <el-resolver>com.sys.resolver.SysLocaleController</el-resolver>
    <resource-bundle>
        <base-name>messages.build</base-name>
        <var>build</var>
    </resource-bundle>
    <resource-bundle>
        <display-name>I18N</display-name>
        <base-name>messages.messages</base-name>
        <var>i18N</var>
    </resource-bundle>
    <locale-config>
        <default-locale>pt_BR</default-locale>
        <supported-locale>en_US</supported-locale>
        <supported-locale>pt_BR</supported-locale>
    </locale-config>
    <message-bundle>messages.messages</message-bundle>

</application>

To use in JSF uses so:

#{i18N.descriptionPortal}

To use in themeleaf uses so:

#{descriptionPortal}

To use in Spring uses so:

@Qualifier(name = { "messageSource"})
@Autowired
public MessageSource messageSource;

Or

@Qualifier(name = { "i18N"})
@Autowired
public SysResourceBundleRead i18N;

Both are the same object, but they use different methods to read the keys, so you need to adjust your class to have this synchronization.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.