Defining MessageSource and LocaleResolver beans in Spring MVC for adding i18n support

13,289

DispatcherServlet.java

public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";

private void initLocaleResolver(ApplicationContext context) {
    try {
        this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
        }
    }
    catch (NoSuchBeanDefinitionException ex) {
        // We need to use the default.
        this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
                    "': using default [" + this.localeResolver + "]");
        }
    }
}

Spring uses some conventional bean name to intialize DispatcherServlet.

In your case, spring will use a default one if no bean named "localeResolver" is found (therefore your custom LocaleResover is ignored).

UPDATE

In messageSource case,

"When an ApplicationContext is loaded, it automatically searches for a MessageSource bean defined in the context. The bean must have the name messageSource. If such a bean is found, all calls to the preceding methods are delegated to the message source. If no message source is found, the ApplicationContext attempts to find a parent containing a bean with the same name. If it does, it uses that bean as the MessageSource. If the ApplicationContext cannot find any source for messages, an empty DelegatingMessageSource is instantiated in order to be able to accept calls to the methods defined above."

quoted from spring doc.

Share:
13,289
Tuna
Author by

Tuna

#SOreadytohelp

Updated on June 04, 2022

Comments

  • Tuna
    Tuna about 2 years

    I'm trying to add i18n support to a Spring MVC project(3.2.0.RELEASE). I have two bundles below /src/main/resources/bundle:

    messageBundle_en.properties
    messageBundle_vi.properties
    

    And the configurations for spring mvc as below:

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="cache" value="false" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:bundle/messageBundle" />
    </bean>
    <bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="vi" />
    </bean>
    <mvc:interceptors>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <property name="paramName" value="lang" />
        </bean>
    </mvc:interceptors>
    

    with above configurations the application is not working. The error was

    org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: No message found under code 'message.home.header.welcome' for locale 'en_US'.
        org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)
        org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:455)
        org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
        org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
    

    I spent many hours comparing with tutorials of adding i18n support. I saw that there is only one difference: bean definitions of CookieLocaleResolver and ReloadableResourceBundleMessageSource have id attributes. So I changed the configurations to

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:bundle/messageBundle" />
    </bean>
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="vi" />
    </bean>
    

    Now it's working well!

    Do ReloadableResourceBundleMessageSource and CookieLocaleResolver require to have ids in their definitions?

    Why doesn't InternalResourceViewResolver need an id?

    Wondering if anyone can give me an explanation in details.

  • Martin Frey
    Martin Frey almost 11 years
    The same counts for messageSource. Spring fetches it by name.
  • Tuna
    Tuna almost 11 years
    messageSource is initialized in AbstractApplicationContext.java