2015-04-01 68 views
2

我一直在尝试更改登录后(我使用Spring Security)用户区域设置。在Grails应用程序的主页中更改用户的语言环境

我试过在Spring Security(onInteractiveAuthenticationSuccessEvent)的成功事件处理程序中更改语言环境,并且还创建了自己的localeResolver并在resources.groovy上注册它。

它似乎适用于除主页以外的所有页面。

这是MyLocaleResolver

class MyLocaleResolver implements LocaleResolver { 

    def springSecurityService 

    private Locale defaultLocale = null; 

    @Override 
    Locale resolveLocale(HttpServletRequest httpServletRequest) { 
     User user = User.findByEmail(springSecurityService.authentication.principal.username) 
     if (user && !defaultLocale) { 
      if (user.lang) { 
       this.defaultLocale = new Locale(user.lang) 
      } else { 
       this.defaultLocale = Locale.ENGLISH 
      } 
     } 
     println "defaultLocale = $defaultLocale" 
     return this.defaultLocale 
    } 

    @Override 
    void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { 
     this.defaultLocale = locale; 
    } 
} 

和resources.groovy部分

localeResolver(MyLocaleResolver){ 
    springSecurityService = ref("springSecurityService") 
} 

更新(2015年7月4日): 我已经试图扩大CookieLocaleResolver的,因为它设置cookie值,它在任何情况下都能正常工作,除了在第一个主页加载中设置了默认语言,而不是我在resolveLocale中设置的那个。

class MyLocaleResolver extends CookieLocaleResolver{ 

def springSecurityService 

@Override 
Locale resolveLocale(HttpServletRequest httpServletRequest) { 
    super.resolveLocale(httpServletRequest) 

    User user = User.findByEmail(springSecurityService.authentication.principal.username) 
    Locale locale 
    if (user) { 
     if (user.lang) { 
      locale = new Locale(user.lang) 
     } else { 
      locale = Locale.ENGLISH 
     } 
     httpServletRequest.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, locale != null?locale:this.determineDefaultLocale(request)); 
    } 
    return (Locale)httpServletRequest.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME); 
} 

}

我已经尝试了differente的做法,虽然我认为这是更好地尝试覆盖的LocaleResolver。我试图在用户登录时更改区域设置,更改我的MongoUserDetailsS​​ervice的loadUserByUsername方法中的defaultLocale。它发生比前一种方法一样,它在洛后效果很好,除了在第一主页加载。

def localeResolver 

@Override 
public UserDetails loadUserByUsername(String username) 
     throws UsernameNotFoundException { 
      User.withTransaction { status -> 
       User user = User.findByEmail(username) 
       if (!user) throw new UsernameNotFoundException(
          'User not found', username) 

       try { 
        localeResolver.setDefaultLocale(user.lang ? new Locale(user.lang) : Locale.ENGLISH) 
       } catch (Exception e){ 
        e.printStackTrace() 
       } 

       def authorities = user.authorities.collect { 
        new SimpleGrantedAuthority(it.authority) 
       } 

       return new MyUserDetails(user.username, user.password, user.enabled, 
        !user.accountExpired, !user.passwordExpired, 
        !user.accountLocked, authorities ?: MongoUserDetailsService.NO_ROLES, user.id, user.client, user.email, 
        user.dateCreated) 
      } 
} 

和resources.groovy

userDetailsService(net.ds.batto.MongoUserDetailsService){ 
    localeResolver = ref("localeResolver") 
} 

另外,我认为用CookieLocaleResolver的Grails的默认情况下,但我已经看到,我得到的localeResolver是SessionLocaleResolver。这是正确的行为还是可能存在配置错误?

+0

不确定是否更好的方法,但它可能值得研究:你有没有考虑覆盖org.springframework.web.servlet.i18n.LocaleChangeInterceptor?我想象改变preHandle方法可能会提供额外的控制首页加载行为。使其更早地意识到已登录的用户。 http://www.oodlestechnologies.com/blogs/Changing-request-Locale-for-i18n-in-grails-application-using-Interceptor – Smithfield 2017-07-12 09:47:17

+0

另外我很惊讶地看到UserDetailsS​​ervice的loadByUserName方法中的Locale修改。更改会话区域设置与从数据库检索/加载用户无关。你没有在消息中最初描述的authenticationSuccessEventListener(com.example.Authenticatio nSuccessEventListene r)中维护它的任何原因? – Smithfield 2017-07-12 10:25:27

回答

0

要我defaultLocale是为整个应用程序的全局配置(或至少不为特定的用户会话)

http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/i18n/SessionLocaleResolver.html

自定义控制器可以通过调用#setLocale覆盖用户的语言环境和时区解析器上(背景)

因此,也许你可以尝试更换

localeResolver.setDefaultLocale(user.lang ? new Locale(user.lang) : Locale.ENGLISH) 

通过

class MyLocaleChangeInterceptor extends LocaleChangeInterceptor { 
     ... 
    @Override 
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { 
     localeResolver.setLocale(user.lang ? new Locale(user.lang):Locale.ENGLISH) 
    } 
} 

直接在LocaleChangeInterceptor,我想这是为时已晚,当服务器达到“的LocaleResolver”请求已被处理,只是下面的请求将被语言环境变化的影响。

相关问题