如何重用 Spring 或 Java 的语言环境查找代码?

cur*_*us1 2 spring locale internationalization

我正在做一个 Spring Web 应用程序。

我需要支持一些语言环境,例如 ko(韩语)、ru(俄语)、en(英语)等。

我能够通过 RequestContextUtils.getLocale(request) 或 LocaleChangeInterceptor 等方式从浏览器中获取语言环境。

但是,浏览器的语言环境可能不是我的网络应用程序支持的。我必须将其解析为壁橱或默认语言环境。

基本上,我需要知道如何根据浏览器的语言环境和一些语言环境值(例如 ko、ru 和 en)获取解析的语言环境。

我的理解是 Spring 具有这样的语言环境解析代码,因为它能够根据浏览器的语言环境找到正确的资源包。我希望重用 Spring 的代码进行区域设置解析,但不知道该怎么做。请注意,此问题与查找浏览器的语言环境或显示正确的消息无关。

编辑

根据我跟踪 Spring 的代码,Spring 似乎依赖 JDK 来查找确切或最接近的语言环境。我刚刚发现了这一点,并认为这就是我要找的:

资源包查找顺序 https://sites.google.com/site/openjdklocale/design-notes/resource-bundle-lookup-order

请注意,我不需要找到正确的资源包。我只需要获取现有 JDK 代码返回的语言环境,给出一个有问题的语言环境和一些已知的语言环境。所以我希望重用现有的 JDK 的查找代码。任何的想法?

我正在使用 JDK 7。


感谢您的任何帮助和输入!

问候。

Pav*_*ral 5

简答

你查过官方文档了吗(17.8 使用 locales章节)?您需要配置LocaleResolver一个LocaleChangeInterceptor(或自己编写)。

关于 Spring 工作原理的详细描述

请注意,解析客户端的语言环境与获取正确的资源包是不同的任务。

  • Spring使用LocaleResolver获取或设置当前的语言环境。不同的策略有几种实现方式LocaleResolver
    • FixedLocaleResolver - 将始终将语言环境解析为预定义值(无法设置不同的语言环境)
    • SessionLocaleResolver - 存储并解析区域设置为特殊键下的会话值存储
    • AcceptHeaderLocaleResolver - 这是实际尝试从浏览器获取语言环境的解析器(无法设置不同的语言环境)
    • CookieLocaleResolver - 将区域设置存储并解析为存储在浏览器库中的值

LocaleResolver用于填充LocaleContextHolder(顺便说一句,这是您应该从中获取语言环境的类)。

还有第二种机制LocaleChangeInterceptor,它能够LocaleResolver根据用户请求参数通过您选择的区域设置。

现在,此基础结构与您的资源包(messages.properties、messages_en.properties 等)以及用于解析消息的机制无关。以下示例将说明原因。

示例场景

  • 让我们假设您的资源包是:
    • messages.properties- 带有ru消息(默认消息)
    • messages_ko.properties- 有ko消息
  • 假设您已经配置SessionLocaleResolver了默认语言环境ru
  • 让我们假设你已经配置 LocaleChangeInterceptor

场景I - 第一个请求:

  1. 用户向应用程序发出第一个请求
  2. 一旦请求到达 Spring,DispatcherServlet它就会查询LocaleResolver以获取请求的语言环境
  3. 会话上没有设置语言环境,因此语言环境被解析为ru(默认)
  4. ...处理程序的东西...
  5. 现在您正在渲染网页并且您想使用<spring:message>标签...
  6. 该标签尝试使用带有请求语言环境的预配置MessageSource( ResourceBundleMessageSource)来解析翻译代码(这是由您的解析器解析的)。
  7. 消息源尝试加载messages_ru.properties不存在的翻译代码,因此它移动到更通用的文件messages.properties(“偶然”包含您的默认语言 - ru
  8. 用户以俄语获取他的页面

场景 II - 用户单击链接将其语言更改为ko

  1. 第二个请求是使用查询参数发出的 locale=ko
  2. DispatcherServlet将请求语言环境解析为ru(这是您的语言环境解析器返回的内容)
  3. 在请求被移交给您的处理程序之前,它会通过LocaleChangeInterceptor处理程序拦截器。
  4. LocaleChangeInterceptor在您的 上检测locale查询参数和调用setLocale方法LocaleResolver,这会导致更改请求区域设置并在会话中存储新区域设置以供将来请求使用。
  5. ...处理程序的东西...
  6. ...查看内容...
  7. 现在<spring:message>正在MessageSourceko语言环境调用。
  8. 消息源尝试加载messages_ko.properties并成功。
  9. 用户获取他的韩文页面

场景 III - 用户尝试更改为无效区域设置:

  1. 用户使用查询参数发出请求locale=en
  2. ...调度员的东西...(区域设置ko从会话中解析)
  3. 处理程序拦截器将区域设置更改为en(这也将存储在会话中)
  4. ...处理程序的东西...
  5. ...查看内容...
  6. 现在<spring:message>正在MessageSourceen语言环境调用。
  7. 消息源会尝试加载messages_en.properties不存在的文件messages.properties,因此它会移动到更通用的文件,并将消息转换为ru,即使请求区域设置为en
  8. 用户以俄语获取他的页面

概括

现在最后一个例子可能让你感到困扰——没有检查用户选择的语言环境是否受支持。如果您不想让用户切换到不受支持的语言环境,那么您需要子类化 someLocaleResolver或编写自己的LocaleChangeInterceptor.