Spring保存语言环境并在用户登录时更改语言环境

我有一个spring应用程序,我希望用户能够更改首选语言环境。 目前,用户可以更改当前会话的区域设置,但我希望能够保存用户选项,这样无论何时登录,都会使用已保存的区域设置(如果存在)。 我有一个mysql数据库,我用它来存储用户区域设置首选项。 我创建了一个自定义AuthenticationSuccessHandler来处理将语言环境更改为已保存的语言环境,该语言环境适用于已将语言环境保存到数据库的用户。 但是,我不知道该怎么做的是在更改选项时保存语言环境。 代码如下:

/** * 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类:

 @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) ; } .... } 

AuthenticationSuccessHandler类

 @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); } } } } } 

显示语言更改选项的html页面的一部分:

 
Language English 中文 Deutsch Español Français

更改语言选项的Javascript:

 $('#language-selector').change(function() { var languageSelectedUrl = $(this).find("option:selected").val(); if (languageSelectedUrl) { window.location = languageSelectedUrl; } }); 

您可以实现LocaleResolver接口以将用户区域设置绑定到数据库。 示例实现“ApplicationLocaleResolver.java”如下所示

 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); } } 

我假设您的userService有一个方法可以将本地用户保存到db。 我更喜欢userService.saveUsersPreferedLocaleOption(userName, locale); 你可以改变它。

然后您可以替换localeResolver bean定义,如下所示。

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