在 Spring MVC 中动态生成可用语言列表
我已经在 Spring MVC 3 中设置了 i18n,并且它工作正常。 有几个文件,每个文件都有自己的语言:messages_en.properties、messages_de.properties 等。
在我的一个 JSP 中,我需要向用户显示包含所有可用语言的组合,并且我希望此列表是动态的,即从服务器中现有的语言文件即时生成。
是否有任何内置方法可以生成此列表?或者我是否必须检查语言文件所在的文件夹并解析它们?
谢谢!
纳乔
I have set up i18n in Spring MVC 3, and it is working correctly.
There are several files, each with its own language: messages_en.properties, messages_de.properties, etc.
In one of my JSPs, I need to show the users a combo with all available languages, and I would like this list to be dynamic i.e. generated on the fly from the existing language files in the server.
Is there any built-in method to generate this list? Or do I have to resort to check the folder where the language files reside and parse them?
Thanks!
Nacho
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如何将其放入可以访问 ReloadableResourceBundleMessageSource 的内容中?
只需确保每种受支持的语言提供
test.code
值即可。How about putting this into something that has access to the
ReloadableResourceBundleMessageSource
?Just make sure each supported language supplies a
test.code
value and you're done.想法如下:在
.properties
文件中创建test
变量,该变量的内容必须是 ISO 国家名称(2 个符号,例如:Russia=RU)。对于默认区域设置,您可以设置test=DEFAUL
。文件夹结构和资源包内容:
代码结果:
Idea is following: create
test
variable in your.properties
file and content of this variable must be ISO country name (2 symbols e.g: Russia=RU). For default locale you can settest=DEFAUL
.Folder structure and resource bundle content:
Code result:
这将是一个很好的功能,但我认为您不会找到内置方法,因为属性文件的“失败”机制意味着拥有 messages_de.properties 不会必然意味着每条消息都有德语版本。所以 Spring 无法构建一个很好的
Map
来从中获取密钥。不过,您应该能够使用 Spring 来使您的工作变得更轻松,而不必自己访问文件系统:
ResourceBundle
ClassLoader
中获取ResourceBundleMessageSourceClassLoader
来列出所有“消息”资源:Enumeration; allMsgs = bundleClassLoader.findResources("messages");
Enumeration
,获取语言环境(en
、de
等) ) 来自每个URL
的部分It would be a nice feature, but I don't think you'll find a built-in method because the "fall-through" mechanism of properties files means that having a messages_de.properties doesn't necessarily mean every message is available in German. So Spring can't build up a nice
Map<Locale, ResourceBundle>
from which you could obtain the keys.You should be able to use Spring to make your job easier though, and not have to hit the filesystem yourself:
ResourceBundle
ClassLoader
from Spring's ResourceBundleMessageSourceClassLoader
to list all the "messages" resources:Enumeration<URL> allMsgs = bundleClassLoader.findResources("messages");
Enumeration
, getting the locale (en
,de
etc) part from eachURL
好的,找到了两个解决方案。对于两者,假设它们在 Spring MVC
@Controller
注解的类中执行。每个都会生成一个 HashMap (languages
),其中键是 2 个字母的 ISO 语言代码,值是语言名称(在当前区域设置中,在这些示例中是一个名为 < code>HSConstants.currentLocale)1.- 由 @millhouse 提交的(见上文/下文),经过一些调整后即可工作:
此解决方案要求在每种语言 .properties 文件中设置带有语言的条目(在上面的示例中,它将是“currentLanguage”)。例如,在 messages_it.properties 中,必须有这样的条目: currentLanguage=Italiano
2.- 原始方法,即直接访问文件夹/文件:假设文件语言位于 /WEB-INF/languages 中,并且具有基本名称fr-messages:
然后,在您的 JSP 中,使用
languages
映射呈现选择框:Ok, two solutions found. For both, assume they are being executed inside a Spring MVC
@Controller
-annotated class. Each will produce a HashMap (languages
) in which the key is the 2-letter ISO language code, and the value the language name (in the current Locale, which in these examples is a static variable calledHSConstants.currentLocale
)1.- The one submitted by @millhouse (see above/below), which works after a bit of tweaking:
This solution requires that, in each of your language .properties files, you set an entry with the language (in the example above, it would be 'currentLanguage'). For ecample, in messages_it.properties, there must be an entry like this: currentLanguage=Italiano
2.- Raw method, i.e. accesing the folder/files directly: assuming the files languages are in /WEB-INF/languages, and have a basename of fr-messages:
And then, in your JSP, render the select box using the
languages
map:我想与大家分享我的解决方案。
当前问题的经过验证的响应(具有两个解决方案)确实很有趣。
第一个解决方案的唯一问题是使用硬编码消息键(“currentLanguage”),该键可能会从相应的属性文件中消失。
第二个需要对属性文件的基本名称(“fr-messages_”)进行硬编码。但文件名可以更改...
因此,我按照经过验证的响应的示例来扩展我的自定义 ResourceBundleMessageSource 来执行此操作。
最初,我需要获取 Spring 消息属性文件的内容(messages_en.properties、messages_fr.properties,...),因为我有一个完整的 Javascript 前端(使用 ExtJ)。因此,我需要在 JS 对象上加载应用程序的所有(国际化)标签。
但它不存在......出于这个原因,我开发了一个自定义的ReloadableResourceBundleMessageSource类。相应的方法是“getAllProperties()”、“getAllPropertiesAsMap()”和“getAllPropertiesAsMessages()”。
后来,我需要获取应用程序上可用的区域设置。阅读此 stackoverflow 页面后,我想到了扩展我的 ReloadableResourceBundleMessageSource 类来做到这一点。您可以看到“getAvailableLocales()”和“isAvailableLocale()”(仅测试一种区域设置)方法。
如果你想使用这两个功能(获取可用的 Locales 并从属性文件中获取所有 Spring 消息),那么你需要获取这个完整的类。
使用这个ReloadableResourceBundleMessageSource非常简单。
您需要声明资源包:
然后,您只需将资源包注入到您想要获取可用Locale的类中:
这里是一个使用示例,用于在自动更新浏览器的浏览Locale之前检查Locale是否可用当 Spring LocaleChangeInterceptor 检测到更改时数据库上的用户(例如通过 URL => 'http://your.domain? lang=en'):
相应的 SessionLocaleResolver 声明:
我希望这对您有用...
享受吧! :-)
I wish to share with you my solution.
The validated response (with the two solutions) of the current question is really interresting.
The only problem on the first solution is to use a hard coded message key ("currentLanguage") that can disappear from the corresponding properties file.
The second one needs to hard code the basename ("fr-messages_") of the properties file. But the file name can be changed...
So, I followed the example of the validated response to extend my custom ResourceBundleMessageSource to do that.
Initialy, I needed to get the content of the Spring message properties files (messages_en.properties, messages_fr.properties, ...) because I have a full Javascript front end (using ExtJs). So, I needed to load all the (internationalized) labels of the application on a JS object.
But it doesn't exist... For this reason, I have developed a custom ReloadableResourceBundleMessageSource class. The corresponding methods are "getAllProperties()", "getAllPropertiesAsMap()" and "getAllPropertiesAsMessages()".
Later, I needed to get the available Locales on the application. And reading this stackoverflow page, I had the idea to extend my ReloadableResourceBundleMessageSource class to do that. You can see the "getAvailableLocales()" and "isAvailableLocale()" (to test just one Locale) methods.
If you want to use the two functionnalities (get the available Locales and get all Spring messages from the properties files), so you need to get this complete class.
To use this ReloadableResourceBundleMessageSource, it is really simple.
You need to declare the resource bundle :
Then, you just need to inject the resource bundle into the class where you want to get the available Locales:
Here is a usage example to check if the Locale is available before automatically update the browsing Locale of the User on database when the Spring LocaleChangeInterceptor detect a change (via URL for example => 'http://your.domain?lang=en'):
The corresponding SessionLocaleResolver declaration:
I hope this will be useful to you...
Enjoy! :-)
如果有人仍在寻找简洁的答案,希望这会有所帮助:
想法是
Autowire
所有可用的消息源messages_*.properties
并根据文件名派生可用的区域设置。默认区域设置可以单独标记为受支持,如下所示:
Hope this helps, if anyone is still looking for a concise answer:
The idea is to
Autowire
all available message sourcesmessages_*.properties
and derive the available locales depending on the filenames.The default locale could be marked separately as supported like so: