Pardon me if this question has been asked before, but I haven't gotten a straight answer that helped me solve my problem. I have a gwt application that I have secured using spring-security. Spring security just authenticates the user and redirects to the gwt application. Now i want the user to be able to change the locale from a link on the login page after which the locale will be stored on a cookie and used in the app.
I have the following configurations, in my applicationContext.xml
<http auto-config="true">
<intercept-url pattern="/mywebapp/**" access="ROLE_USER"/>
<intercept-url pattern="/gwt/**" access="ROLE_USER"/>
<intercept-url pattern="/**/*.html" access="ROLE_USER"/>
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<form-login login-page="/login.jsp"/>
</http>
<beans:bean id="userDetailsService"
class="com.kibet.mywebapp.server.auth.UserDetailsServiceImpl">
</beans:bean>
...
<!-- Application Message Bundle -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:messages" />
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<beans:bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<beans:property name="defaultLocale" value="pt"/>
</beans:bean>
<beans:bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="localeChangeInterceptor"/>
</beans:list>
</beans:property>
<beans:property name="mappings">
<beans:value>/login.jsp=userDetailsService</beans:value>
</beans:property>
</beans:bean>
This doesn't seem to work. I have the locale properties files messages_en.properties, messages_es.properties and messages_pt.properties in my classpath. The only time it works is when I change the browsers default locale. As far as I can tell, the login page is generated by spring-security and the handler mapping cannot intercept the locale change request. If this is the reason how would I go about this? Help is highly appreciated.
Here's my Custom filter code.
public class InternationalizationFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
String newLocale = request.getParameter("lang");
if (newLocale != null) {
Locale locale = StringUtils.parseLocaleString(newLocale
.toLowerCase());
LocaleContextHolder.setLocale(locale);
}
try {
filterChain.doFilter(request, response);
} finally {
LocaleContextHolder.resetLocaleContext();
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}}
Thanks @Ritesh for give the answer. You give me a idea to handle this problem. I worked around it on a further way:
public class InternationalizationFilter extends OncePerRequestFilter {
private Logger log=Logger.getLogger(InternationalizationFilter.class);
private String localeParam="lang";
private LocaleResolver localeResolver;
public InternationalizationFilter(String localeParam, LocaleResolver localeResolver) {
this.localeParam = localeParam;
this.localeResolver = localeResolver;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
protected void doFilterInternal(
final HttpServletRequest request,
final HttpServletResponse response,
final FilterChain filterChain)
throws ServletException, IOException {
if (localeResolver == null) {
throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
}
else{
final String newLocale = request.getParameter(localeParam);
if (newLocale != null) {
final Locale locale = StringUtils.parseLocaleString(newLocale.toLowerCase());
LocaleContextHolder.setLocale(locale);
LocaleEditor localeEditor = new LocaleEditor();
localeEditor.setAsText(newLocale);
localeResolver.setLocale(request, response, (Locale) localeEditor.getValue());
log.debug("change locale to "+
locale.getLanguage()+"_"+locale.getCountry()+
" at Thread"+Thread.currentThread().getId());
}
else{
final Locale locale=localeResolver.resolveLocale(request);
LocaleContextHolder.setLocale(locale);
log.debug("restore locale to "+
locale.getLanguage()+"_"+locale.getCountry()+
" at Thread"+Thread.currentThread().getId());
}
try {
filterChain.doFilter(request, response);
} finally {
LocaleContextHolder.resetLocaleContext();
}
}
}
}
With declared the localChangeInterceptor and localeResolver in mvc config file. So we can change locale with request param "lang":
<mvc:interceptors>
<bean id="localChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
</mvc:interceptors>
<!--localeResolver-->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<!--<property name="cookieDomain" value=""/>-->
<property name="defaultLocale" value="zh"/>
</bean>
In the security config file,I made a i18nFilter and added it to the Filter Chain:
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**/*.css" filters="
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/**/*.jpg" filters="
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/**/*.png" filters="
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/**/*.gif" filters="
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/**/*.js" filters="
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/**/*.cur" filters="
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/**/*.swf" filters="
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/login" filters="
i18nFilter,
securityContextPersistenceFilter,
exceptionTranslationFilter"/>
<security:filter-chain pattern="/checkin" filters="
i18nFilter,
securityContextPersistenceFilter,
authenticationFilter"/>
<security:filter-chain pattern="/**" filters="
i18nFilter,
securityContextPersistenceFilter,
authenticationFilter,
logoutFilter,
anonymousAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<bean id="i18nFilter" class="com.bjinfotech.filter.InternationalizationFilter">
<constructor-arg name="localeParam" value="lang"/>
<constructor-arg name="localeResolver" ref="localeResolver"/>
</bean>
with localChangeInterceptor & localeResolver,I can change locale and save locale into session or cookie.
under localeResolver's help,InternationalizationFilter could store/restore locale and make change to LocaleContextHolder's locale.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With