Search code examples
spring-mvcinternationalizationlocaleresourcebundle

i18n with Spring MVC, skip RequestMapping


I have set up i18n to my web app using Spring.It works fine.But I have a problem.When I click link to different language,from, lets say edit_user page. The request url is generated as '/edit_user.htm?lang=de'.Controller class receives this request and run editUser method based on @RequestMapping(value = { "edit_user" }). How to avoid this from happening.I just want my web app to be able to simply change the locale without reaching controller class methods when clicked on "change language links". My spring-config-servlet.xml is as following.

<bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:i18n/messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>

    <bean id="localeChangeInterceptor"
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="lang" />
    </bean>

    <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en" />
    </bean>

    <bean id="handlerMapping"
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors">
            <ref bean="localeChangeInterceptor" />
        </property>
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate" />

    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="mediaTypes">
            <map>
                <entry key="pretty" value="text/html" />
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <constructor-arg>
                        <bean class="org.springframework.oxm.xstream.XStreamMarshaller" />
                    </constructor-arg>
                </bean>
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true" />
    </bean>

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="order" value="2" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean
        class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            ....
        </property>
        <property name="defaultErrorView" value="errorPage" />
    </bean>

Solution

  • Hm... Interesting.

    UserController class receives this request:

    <a href="?lang=en">en</a> | <a href="?lang=de">de</a> 
    

    for URL http://www.example.com/AppName/User/edit_user.htm?lang=de and run editUser method.

    But you can change your links to:

    <a href="<c:url value="/?lang=en" />">EN</a> | <a href="<c:url value="/?lang=de" />">DE</a>
    

    and now when user click link to different language HomeController class receives request /?lang=de, web app change the locale and redirect user to the root page http://www.example.com/AppName/?lang=de.

    Is this behavior acceptable for your application?

    Otherwise I guess you have to filter request params for all controller classes if you want to find another solution.