2015-04-01 66 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」請求已被處理,只是下面的請求將被語言環境變化的影響。

相關問題