2015-06-15 17 views
10

İlk Spring MVC 4 uygulamasını i18n desteğiyle oluşturmaya çalışıyorum ve kullanıcı dil uri'yi manipüle ettiğinde varsayılan/geri dönüş yerel ayarını nasıl kullanabileceğimi düşünüyordum Örneğin olmayan bir mevcut veya desteklenen yerel ayar parametre http://localhost.de?lang=abcSpring MVC: uri parametre değerinde bilinmeyen dil kodu için geri dönüş

Im i url ilk defa açarsanız genel olarak çalışır kod

@Bean 
public LocaleResolver localeResolver() { 
    SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver(); 
    sessionLocaleResolver.setDefaultLocale(Locale.GERMAN); 
    return sessionLocaleResolver; 
} 

kullanarak ancak durum için çalışmamasına görünüyor tarif ediyordum. Varsayılan mesajlar özellikleri dosyasını kullanacak bir mekanizma olduğunu biliyorum, ancak bu durum için bir varsayılan/geri dönüş yerel ayarı yapmak istiyorum. Özel bir filtre uygulamak zorunda mıyım?

+0

Hiç kimsenin bir fikri yok mu? Çok arama yapıyordum ama henüz bir çözüm veya fikir bulamadım .... – StephanM

+0

http://localhost.de?lang=abc adresine gittiğinizde ne olur? Bu durumda hangi yerel kullanılır? –

+0

Artık dil kodunu kontrol eden bir filtre oluşturduğumdan sözedemiyorum. Uygulamam bu dili desteklemiyorsa, manuel olarak varsayılan dilime ayarlıyorum. Bu durumda sizin durumunuzda "de" olarak ayarlanacaktır/almanca ... – StephanM

cevap

5

Muhtemelen kadar mükemmel ama bu ı inşa budur olmaktan ...

Ben de ben çünkü SEO biraz ihtiyacı varsayılan dil seçme mekanizması değişti ve ben dili değil değiştirmeye karar olduğunu söylemek gerekir

get parametresi kullanmak yerine bunun yerine seçilen dil için uri yolunun ilk bölümünü kullanır. Örneğin : yerine benim açıklama bazlı yapılandırmada http://myurl.com/test.html?lang=de

ait http://myurl.com/en/test.html:

@Bean 
public LocaleResolver localeResolver() { 
    UriLocaleResolver uriLocaleResolver = new UriLocaleResolver(); 
    return uriLocaleResolver; 
} 

yerel çözümleyici

public class UriLocaleResolver implements LocaleResolver { 

    private final Logger logger = LoggerFactory.getLogger(getClass()); 

    private Locale locale = null; 

    @Autowired 
    private LocalizationService localizationService; 


    @Override 
    public Locale resolveLocale(final HttpServletRequest servletRequest) { 
     if (locale != null) { 
      return locale; 
     } 

     String languageIsoCode = null; 
     try { 
      languageIsoCode = ((String)servletRequest.getAttribute(RequestKey.LANGUAGE_ISO_CODE)).toLowerCase(); 
     } 
     catch (Exception e) { } 
     if (StringUtils.isBlank(languageIsoCode) || !localizationService.getSupportedLocaleLanguageIsoCodes().contains(languageIsoCode)) { 
      logger.trace("Couldn't find valid language iso code. Using default locale '{}'", GlobalConstant.DEFAULT_LOCALE); 
      return GlobalConstant.DEFAULT_LOCALE; 
     } 

     logger.trace("Found language iso code '{}'", languageIsoCode); 
     return new Locale(languageIsoCode); 
    } 

    @Override 
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale)  { 
    this.locale = locale; 
    } 

} 

uri içinde geçerli bir dil kodu için denetler filtre ..

@Component 
public class UriLocalizationFilter extends OncePerRequestFilter { 

    private final Logger logger = LoggerFactory.getLogger(getClass()); 

    @Autowired 
    private LocalizationService localizationService; 


    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 
     String uri = request.getRequestURI().substring(request.getContextPath().length()); 
     String[] pathParts = uri.split("/"); 

     if (!uri.startsWith(GlobalConstant.FRONTEND_RESOURCE_PATH_PREFIX) && pathParts.length >= 1 && pathParts[1].length() == 2) { 
      String originalLanguageIsoCode = pathParts[1]; 
      String lowerCaseLanguageIsoCode = originalLanguageIsoCode.toLowerCase(); 

      if (localizationService.getSupportedLocaleLanguageIsoCodes().contains(lowerCaseLanguageIsoCode)) { 
       logger.debug("Found valid language iso code {}", lowerCaseLanguageIsoCode); 
      } 
      else { 
       logger.debug("Found invalid language iso code {}. Using default language iso code {}.", lowerCaseLanguageIsoCode, GlobalConstant.DEFAULT_LOCALE.getLanguage()); 
       lowerCaseLanguageIsoCode = GlobalConstant.DEFAULT_LOCALE.getLanguage(); 
      } 

      String newUrl = StringUtils.removeStart(uri, '/' + originalLanguageIsoCode); 
      request.setAttribute(RequestKey.LANGUAGE_ISO_CODE, lowerCaseLanguageIsoCode); 
      logger.debug("Dispatching to new url '{}'", newUrl); 
      request.getRequestDispatcher(newUrl).forward(request, response); 
     } 
     else { 
      filterChain.doFilter(request, response); 
     } 
    } 

    public void setLocalizationService(LocalizationService localizationService) { 
     this.localizationService = localizationService; 
    } 

} 

}

Ön uç yolu, js, css, fontlar vb. Gibi tüm statik dosyaların yerleştirildiği durumda "kaynaklar" dır. localizationService.getSupportedLocaleLanguageIsoCodes(), şu anda üç dil kodu içeren bir kümedir (en, ru, de). Bu yüzden abc gibi yanlış bir dil kodunda varsayılan dilim "de" ile bir ileriye doğru gidiyorum. Benim için bu/kabul edilebilir bir çözümdür uri içinde yanlış bir dil koduna sahip olmanın sebebi, uri'nin kullanıcı tarafından manipüle edildiği anlamına gelir.

Belki de "çözüm" değil; Örneğin, nasıl ve eğer çerezlerle çalışıp çalışmadığını ve/veya "beni hatırla" (bahar güvenliğini kullanarak) kimlik doğrulaması yapıp yapmadığımı bilmiyorum ... sadece test etmek için zamanım olmadı ...

7

Benim önerim alt sınıfı

@SpringBootApplication 
public class DemoApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 

    private static Set<Locale> allowedLocales; 

    static { 
     HashSet<Locale> allowed = new HashSet<>(); 
     allowed.add(Locale.GERMAN); 
     allowed.add(Locale.CANADA); 
     allowedLocales = Collections.unmodifiableSet(allowed); 

    } 

    @Bean 
    LocaleResolver localeResolver() { 
     return new LimitedSessionLocaleResolver(); 
    } 

    class LimitedSessionLocaleResolver extends SessionLocaleResolver { 
     @Override 
     public Locale resolveLocale(HttpServletRequest request) { 
      Locale locale = super.resolveLocale(request); 
      if (!allowedLocales.contains(locale)) { 
       return determineDefaultLocale(request); 
      } 
      return locale; 
     } 
    } 
} 

Bu herhangi bir büyük bir şekilde İlkbahar sınıfları değiştirmez ve muhtemelen yakın gelecekte sorunsuz çalışmaya gidiyor: SessionLocaleResolver getLocale yöntemini geçersiz ve.

İlgili konular