当前位置: 首页 > 面试题库 >

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

冯祺
2023-03-14
问题内容

我有一个Spring应用程序,希望用户能够更改首选语言环境。当前,用户可以更改当前会话的语言环境,但是我希望能够保存users选项,以便每当他们登录时,使用已保存的语言环境(如果存在)。我有一个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页面的一部分:

<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:

$('#language-selector').change(function() {

    var languageSelectedUrl = $(this).find("option:selected").val();      
    if (languageSelectedUrl) {
        window.location = languageSelectedUrl;
    }
});

问题答案:

您可以实现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);
    }
}

我假设您的userService具有将用户保存到db本地的方法。我希望userService.saveUsersPreferedLocaleOption(userName, locale);您可以更改它。

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

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


 类似资料:
  • 问题内容: 我在Edittext的addTextChangedListener方法中已自定义,一切正常,但是当我更改语言(语言环境)时,我的addTextChangedListener无法正常工作。 我搜索了我的问题并找到了解决方案: 但我不知道如何使用此代码。 问题答案: 您可以尝试先转换为,然后将其投射到

  • 在我的应用程序中,用户应该能够切换区域设置(用于在页面上呈现文本的语言)。大量教程使用FacesContext.get货币实例()。getViewRoot()。setLocale()。例如:http://www.mkyong.com/jsf2/jsf-2-internationalization-example/.但是,这在JSF 2.0中根本不起作用(它在1.2中确实起作用)。这种语言从不切换。

  • 问题内容: 我希望能够在运行时在Swing应用程序中更改语言环境,并使用来自新语言环境的ResourceBundle的本地化文本来更新屏幕上的所有文本元素。 是否可以在不自定义摆动组件或为处理呈现本地化文本的所有组件创建UIDelegates的情况下完成此操作? 如果没有,那么我可以考虑实施什么好的解决方案? 问题答案: 您有一种方法可用于更改应用程序区域设置(并可能保留新值),而另一种方法可用于

  • 问题内容: 我用来将货币从BigDecimal格式化为字符串。按预期工作,问题在于我们的主要目标是荷兰市场,而默认的荷兰格式很奇怪。 让我解释一下,当格式化-125时,荷兰语将得到“€125-”(预期为“-€125”)。英国按预期方式提供“-£125.50”。 我可以检查语言环境是否为荷兰语,然后在每次我要设置小数格式时都提供一个模式。但是我更喜欢一个解决方案,它可以覆盖荷兰的格式设置。我在考虑以

  • 为应用程序创建多语言支持,可以更改应用程序中的语言设置。 至于现在,一切都适用于英语、西班牙语、法语、俄语,但不适用于印地语和汉语。 1) 我以原始语言指定语言名称,但在应用程序中指定,而不是हिन्दी 我能看到“印地语”。 \res \ values hi \数组。xml 2) 选择“印地语”后结束-实际上选择了默认值(英语) \res\values hi\strings。xml .... 在

  • 主要内容:使用DartPad在线执行脚本,设置本地环境,IDE支持,dart2js工具本章讨论在Windows平台上为Dart设置执行环境。 使用DartPad在线执行脚本 可以使用 https://dartpad.dartlang.org/ 上的在线编辑器在线运行测试脚本。Dart编辑器执行脚本并显示HTML和控制台输出。在线编辑器附带一组预设代码示例。 Dartpad编辑器的截图如下 - Dartpad还可以以更严格的方式进行编码。通过检查编辑器右下角的强模式选项来实现。强模式