Spring save locale and change locale when user logs in

I have a spring application that I want users to be able to change their preferred language. Currently, users can change the locale for the current session, but I want to be able to save the user parameter so that every time I log in, the saved locale is used if it exists. I have a mysql database that I use to maintain user locale preference. I created a custom AuthenticationSuccessHandler to handle locale changes in a saved locale that works for a user where I already saved the locale in the database. However, a bit that I do not know how to do is to save the locale when changing the parameter. The code is as follows:

/** * Creates and gets the LocaleResolver * @return LocaleResolver */ @Bean public LocaleResolver localeResolver() { SessionLocaleResolver slr = new SessionLocaleResolver(); slr.setDefaultLocale(Locale.getDefault()); logger.debug("Setting locale to: " + Locale.getDefault()); return slr; } /** * Creates and gets the LocaleChangeInterceptor * @return LocaleChangeInterceptor */ @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); lci.setParamName("lang"); logger.debug("localeChangeInterceptor called " + Locale.getDefault()); return lci; } 

SecurityConfig Class:

 @Configuration("SecurityConfig") @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled=true) class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired @Qualifier("CustomAuthenticationSuccessHandler") private CustomAuthenticationSuccessHandler authenticationSuccessHandler; @Override protected void configure(HttpSecurity http) throws Exception { CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding(StandardCharsets.UTF_8.name()); filter.setForceEncoding(true); http.addFilterBefore(filter,CsrfFilter.class); // configure authentication providers http.authenticationProvider( customAuthenticationProvider() ); http.authenticationProvider( authenticationProvider() ); http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/?lang=**").permitAll() .antMatchers("/login**").permitAll() .antMatchers("/about**").permitAll() .antMatchers("/index.html").permitAll() .antMatchers("/css/**").permitAll() .antMatchers("/js/**").permitAll() .antMatchers("/img/**").permitAll() .antMatchers("/fonts/**").permitAll() .antMatchers("/errors/**").permitAll() .antMatchers("/error/**").permitAll() .antMatchers("/webjars/**").permitAll() .antMatchers("/static/**").permitAll() .antMatchers("/information/**").permitAll() .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/home") .failureUrl("/login?failedlogin=true") .usernameParameter("username").passwordParameter("password") .successHandler(authenticationSuccessHandler) .failureHandler(authenticationFailureHandler) .permitAll() .and() .logout() .deleteCookies("JSESSIONID") .addLogoutHandler(getCustomLogoutSuccessHandler()) .invalidateHttpSession(true) .permitAll() .and() .csrf().disable() .exceptionHandling() .and() .rememberMe().rememberMeParameter("remember-me").tokenRepository(tokenRepository) .tokenValiditySeconds(86400) ; } .... } 

Authentication ClassSuccessHandler

 @Component("CustomAuthenticationSuccessHandler") public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { /** Logger */ private static final Logger logger = LogManager.getLogger(CustomAuthenticationSuccessHandler.class); @Autowired private LocaleResolver localeResolver; @Autowired @Qualifier("UserService") private UserService userService; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { logger.debug("CustomAuthenticationSuccessHandler.onAuthenticationSuccess called"); setLocale(authentication, request, response); super.onAuthenticationSuccess(request, response, authentication); } protected void setLocale(Authentication authentication, HttpServletRequest request, HttpServletResponse response) { logger.debug("CustomAuthenticationSuccessHandler.setLocale called"); if (authentication != null &&authentication.getPrincipal() != null) { String username = (String) authentication.getPrincipal(); if (username != null) { String localeOption = userService.getUsersPreferedLocaleOption(username); logger.debug("localeOption " + localeOption); if (localeOption != null && !localeOption.isEmpty()) { Locale userLocale = Locale.forLanguageTag(localeOption); localeResolver.setLocale(request, response, userLocale); } } } } } 

The part of the html page that shows the options for changing the language:

 <form id="change-language-form" name="change-language-form" class="change-language-form ng-pristine ng-valid" method="POST"> <div class="row"> <div class="text-right col-sm-offset-8 col-sm-4"> <select id="language-selector" name="language-selector" class="language-selector"> <option value="">Language </option> <option value="?lang=en_GB">English </option> <option value="?lang=zh">中文 </option> <option value="?lang=de_DE">Deutsch </option> <option value="?lang=es_ES">Español </option> <option value="?lang=fr_FR">Français </option> </select> </div> </div> <div class="row"> <div class="spacer-sml"></div> </div> </form> 

Javascript that changes the language parameter:

 $('#language-selector').change(function() { var languageSelectedUrl = $(this).find("option:selected").val(); if (languageSelectedUrl) { window.location = languageSelectedUrl; } }); 
+7
java spring-mvc
source share
1 answer

You can implement the LocaleResolver interface to bind Locale users to the database. An example implementation of "ApplicationLocaleResolver.java" below

 import java.util.Locale; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.servlet.i18n.SessionLocaleResolver; import net.app.locale.service.UserService; @Configuration public class ApplicationLocaleResolver extends SessionLocaleResolver { @Autowired UserService userService; @Override public Locale resolveLocale(HttpServletRequest request) { SecurityContext securityContext = SecurityContextHolder.getContext(); String userName = securityContext.getAuthentication().getName(); String localeOption = userService.getUsersPreferedLocaleOption(userName); Locale userLocale = Locale.forLanguageTag(localeOption); return userLocale; } @Override public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { super.setLocale(request, response, locale); SecurityContext securityContext = SecurityContextHolder.getContext(); String userName = securityContext.getAuthentication().getName(); userService.saveUsersPreferedLocaleOption(userName, locale); } } 

I assume your userService has a method that stores users locally in db. I prefer userService.saveUsersPreferedLocaleOption(userName, locale); You can change it.

You can then replace the localeResolver bean definition as shown below.

 @Bean(name = "localeResolver") public LocaleResolver localeResolver() { return new ApplicationLocaleResolver(); } 
+4
source share

All Articles