我有一个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;
}
Run Code Online (Sandbox Code Playgroud)
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)
;
}
....
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
显示语言更改选项的html页面的一部分:
<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>
Run Code Online (Sandbox Code Playgroud)
更改语言选项的Javascript:
$('#language-selector').change(function() {
var languageSelectedUrl = $(this).find("option:selected").val();
if (languageSelectedUrl) {
window.location = languageSelectedUrl;
}
});
Run Code Online (Sandbox Code Playgroud)
您可以实现LocaleResolver接口以将用户Locale绑定到数据库.示例实现"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);
}
}
Run Code Online (Sandbox Code Playgroud)
我假设您的userService有一个方法可以将本地用户保存到db.我更喜欢userService.saveUsersPreferedLocaleOption(userName, locale);你可以改变它.
然后,您可以替换localeResolver bean定义,如下所示.
@Bean(name = "localeResolver")
public LocaleResolver localeResolver() {
return new ApplicationLocaleResolver();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4141 次 |
| 最近记录: |