6

我的第一個問題在這裏,我會盡量具體。我對Spring很陌生,我試圖創建一個相當簡單的預訂系統(但這實際上並不重要)。重要的是,我正在創建一些基本模板,然後由真正的網頁填寫。應用程序在hibernate,mysql上工作,我還設置了i18n和spring安全。問題是我無法更改我的語言環境。唯一可行的是改變默認的一個。 首先我瀏覽Web A LOT,並且發現使用i18n和spring安全性通常比較複雜。我發現了什麼是我需要有額外的過濾器:Spring security + i18n =如何讓它一起工作?

<filter> 
    <filter-name>localizationFilter</filter-name> 
    <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>localizationFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

我發現了什麼是這個過濾器的一個安全但它不解析的形式請求之前的確處理:http://someserver.com/bla/home?locale=en。我調試了它,它似乎不是爲此目的而創建的(而這正是我需要的)。 這是從春季樣本「聯繫人」中提取的,但在本例中,我找不到任何實際上以更改語言爲目標的代碼。效果是,它根本不起作用。它總是試圖將區域設置更改爲我的默認設置。好消息是,如果在調試模式下,我手動將locale-to-set更改爲其他一個工作正常,所以我在我的心中感受到了希望...... ;-)

然後我找到了其他一些方法 - 通過創建我們自己的過濾器。我所做的就是將創建的示例(不要記住作者)與創建方法RequestContextFilter合併在一起。畢竟RequestContextFilter工作正常 - 只要最好解析我的請求。這是新過濾器的代碼:

public class InternationalizationFilter extends OncePerRequestFilter { 

@Override 
public void destroy() { 
    // TODO Auto-generated method stub 

} 


@Override 
protected void doFilterInternal(final HttpServletRequest request, 
     final HttpServletResponse response, final FilterChain filterChain) 
     throws ServletException, IOException { 
    final String newLocale = request.getParameter("locale"); 
    if (newLocale != null) { 
     final Locale locale = StringUtils.parseLocaleString(newLocale 
       .toLowerCase()); 
     LocaleContextHolder.setLocale(locale); 
    } 
    try { 
     filterChain.doFilter(request, response); 
    } finally { 

     LocaleContextHolder.resetLocaleContext(); 
    } 
} 

} 

正如您所看到的,請求參數區域設置被解析並設置了區域設置。有兩個問題: 1.發送請求xxxxx?locale=en後,它創建沒有「國家」屬性的語言環境(僅設置語言)。說實話,我不知道這是否有問題 - 也許不是。 2.更嚴重的問題是,它不起作用...我的意思是它在過濾器鏈中的正確位置(在安全之前),它產生正確的語言環境並將其設置爲像RequestContextFilter一樣的方式。 ..但它根本無法工作。

我將非常高興,如果有人可以讓我知道如何讓我給出的例子或任何其他帶有彈簧安全築底國際化的工作...

謝謝!

其他信息: 我做了一些實驗,看起來來自請求的Locale實例是某種特定的。

看看這段代碼(修改RequestContextFilter類):

@Override 
protected void doFilterInternal(final HttpServletRequest request, 
     final HttpServletResponse response, final FilterChain filterChain) 
     throws ServletException, IOException { 

    final ServletRequestAttributes attributes = new ServletRequestAttributes(
      request); 
    final Locale l = Locale.GERMAN; 
    final Locale l2 = request.getLocale(); 
    LocaleContextHolder.setLocale(l, 
      this.threadContextInheritable); 
    RequestContextHolder.setRequestAttributes(attributes, 
      this.threadContextInheritable); 
    if (logger.isDebugEnabled()) { 
     logger.debug("Bound request context to thread: " + request); 
    } 
(...) 

如果這種方法:LocaleContextHolder.setLocale(l, this.threadContextInheritable); 我通過語言環境「L」它不能在所有的工作。我的意思是即使你明確改變了語言環境也不會改變。 另一方面,如果我通過那裏修改爲德語的locale'l2'(在調試模式下),它工作正常!

這意味着,由於某種原因,從request.getLocale()的Locale實例莫名其妙的青睞,或許真的是後來事情的代碼,我不知道/ understant ...

請讓我知道應該怎麼我將這個i18n與安全原因一起使用,我必須承認我不知道發生了什麼......

- ==== - ====== - ====== - ====== - ====

最終解決方案/ ANSWER(但仍與小問題) 感謝拉爾夫我設法解決我的問題。以前我走錯了方向,但roo生成的項目推動了我前進。 看來,我不斷添加在一個錯誤的/不準確的方法攔截器(以前的代碼):

<bean id="localeChangeInterceptor" 
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> 
</bean> 
<bean id="localeResolver" 
    class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> 
    <property name="defaultLocale" value="pl"/> 
</bean> 
<bean id="handlerMapping" 
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
    <property name="interceptors"> 
     <ref bean="localeChangeInterceptor" /> 
    </property> 
</bean> 

這樣的攔截器從未援引出於某種原因。

改變攔截器高清後:

<mvc:interceptors> 
<bean id="localeChangeInterceptor" 
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> 
</bean> 
</mvc:interceptors> 

<bean id="localeResolver" 
    class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> 
    <property name="defaultLocale" value="pl"/> 
</bean> 

<bean id="handlerMapping" 
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
</bean> 

...它啓動時沒有任何其他更改安全/ web.xml中正常工作。

現在問題沒有了,但我不知道發生了什麼。根據我在第二個例子(工作的那個)中的理解,我製作了攔截器「全局」。但是爲什麼在第一個例子中定義的攔截器不起作用?任何提示?

再次感謝您的幫助! N.

+0

嗨,我已經嘗試過你的配置攔截器,但它不工作。我的語言環境在登錄頁面上沒有變化,但成功登錄後它的工作正常。在登錄頁面上,它只會觸發系統區域設置。 –

回答

1
  1. 後發送請求XXXXX?區域= EN它沒有 「國家」 創造語言環境屬性(唯一的語言設置)。

這是預期的行爲。在Java中有某種層次結構。 語言比國家更普遍。

背後的想法是,你可以例如在更常見的languge中的文本,但在國家特定的文件中的一些單位(如貨幣)。

@see:http://java.sun.com/developer/technicalArticles/Intl/IntlIntro/


  1. 更嚴重的問題是,它不工作...

應該沒有任何手工工作取得執行!

您需要註冊Local Change Interceptor,並且需要爲登錄頁面設置permitAll。

<mvc:interceptors>   
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/> 
</mvc:interceptors> 

<http auto-config="true" use-expressions="true"> 
    <form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t"/> 
    <logout logout-url="/resources/j_spring_security_logout"/> 

    <!-- Configure these elements to secure URIs in your application --> 
    <intercept-url pattern="/login" access="permitAll" /> 
    <intercept-url pattern="/resources/**" access="permitAll" /> 
    <intercept-url pattern="/**" access="isAuthenticated()" /> 
</http> 

要查看此示例運行,創建一個袋鼠項目與袋鼠腳本:

// Spring Roo 1.1.5.RELEASE [rev d3a68c3] log opened at 2011-12-13 09:32:23 
project --topLevelPackage de.humanfork.test --projectName localtest --java 6 
persistence setup --database H2_IN_MEMORY --provider HIBERNATE 
ent --class ~.domain.Stuff 
field string --fieldName title 
controller all --package ~.web 
security setup 
web mvc language --code de 
web mvc language --code es 

那麼你只能更改安全過濾器intersept的URL模式,比如我上面顯示(applicationContext-security.xml)!

現在你有一個應用程序,用戶可以通過應用程序(當用戶登錄)局部變化攔截改變其本地以及時未登錄他(在登錄頁面)

+0

好的感謝您的快速回答 - 這就是我的預期。也許你可以把我放在正確的道路上,以防萬一主要問題(場所變化)。再次感謝! – Nirwan

+0

@Nirwan:看到我的擴展答案 - 它並沒有真正解釋爲什麼它不適合你,但它引導你一個本地更改攔截器運行良好的例子。 – Ralph

+0

謝謝拉爾夫。通過roo的例子,我終於實現了它的運行。就像你所說的那樣,沒有必要手動執行......請看看我的問題,瞭解詳情有什麼不對的地方 - 也許你可以告訴我我究竟做了什麼,導致我不確定;)無論如何再次感謝! ! – Nirwan

0

我在使用GWT應用程序時遇到了與本地化相似的問題。我注意到的問題是,當我們映射

<filter-mapping> 
<filter-name>localizationFilter</filter-name> 
<url-pattern>/*</url-pattern> 
</filter-mapping> 

的過濾器,即使圖像請求路由到過濾器。這些請求有時會省去locale參數,因此當多個請求碰到過濾器時,Locale參數不是。因此,只要我收到語言環境參數,我就把它放在一個會話中。記錄所有請求頭和值,您可能會找到根本原因。

相關問題