我想检查ResourceBundle的存在而不实际加载它.
通常,我正在使用Guice,并且在初始化时,我想检查存在,而在执行时,我想加载它.如果捆绑不存在,我想要早期报告RB的不存在.
如果有可能获得用于特定ResourceBundle的ResourceBundle.Control实例,我将获得构建实际资源名称的基本信息(使用toBundleName()和toResourceName())没有问题,但事实并非如此.那个级别.
编辑:
好的,我找到了办法.我将创建一个可扩展的ResourceBundle.Control(使用custom addFormat(String,Class))来存储所有包格式,然后使用我自己的另一种方法检查特定语言环境的所有可能的文件名(使用Class. getResource,如下所示).
编码说:
class MyControl extends ResourceBundle.Control {
private Map<String,Class<? extends ResourceBundle>> formats = new LinkedHashMap();
public void addFormat(String format,Class<? extends ResourceBundle> rbType) {
formats.put(format, rbType);
}
public boolean resourceBundleExists(ClassLoader loader, String baseName, Locale locale) {
for (String format: formats.keySet()) {
// for (loop on locale hierarchy) {
if (loader.getResource(toResourceName(toBundleName(baseName, locale), format)) != null) {
return true;
}
// }
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一些Junit测试来测试我们的应用程序中的旧类.代码正在尝试加载ResourceBundle(用于翻译)但失败了.我想问题是类路径相关但我无法弄明白.
代码在/ src中布局,我的测试在/ test中.在给定相对于/ src的基本名称的情况下加载ResourceBundle,例如"foo/bar/baz".
我的测试使用与app本身相同的类路径,所以我不明白它为什么找不到捆绑包.
对于什么是错的任何想法?
显然ResourceBundle需要在找到的文件中使用类似语法的属性文件.
我们有一种情况,我们想要将整个文件(在我们的例子中是HTML文件)用作"值".这意味着我们没有这样的密钥.好吧,也许文件名可以作为密钥.
这是一个目录树:
src/
main/
resources/
html/
content.html
content_de.html
content_fr.html
content_es.html
order.html
order_de.html
order_fr.html
order_es.html
Run Code Online (Sandbox Code Playgroud)
现在我们需要逻辑来根据当前的语言环境找到正确的文件.如果当前的语言环境是德语,我正在查找html/content.html文件,它应该找到html/content_de.html.它不一定需要立即加载它.Java中是否存在一些现有机制?我们需要手动完成吗?
由于某些限制,我们目前正计划不使用任何第三方库.因此,如果Java 6 SE中有可用的东西,它将是我们的最佳选择; 但是,如果您知道第三方库,请随意命名.
编辑#1:一个明显的解决方案是使用密钥messages.properties来命名该HTML文件.虽然这会起作用,但从长远来看它可能会成为一个痛苦(除此之外,我不认为这会解决我们所有的问题).
编辑#2:我忘了说这是一个桌面应用程序.
我在WEB-INF/i18n目录下有两个文件:
我已正确配置我的ReloadableResourceBundleMessageSource bean如下(spring mvc):
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:basenames="WEB-INF/i18n/messages,WEB-INF/i18n/application"
p:fallbackToSystemLocale="false"/>
Run Code Online (Sandbox Code Playgroud)
然而我从Spring mvc得到这个:
2012-09-03 02:59:45,911 [http-bio-8080-exec-4] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - Loading properties [application.properties]
2012-09-03 02:59:45,912 [http-bio-8080-exec-4] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - No properties file found for [WEB-INF/i18n/application_fr] - neither plain properties nor XML
2012-09-03 02:59:45,912 [http-bio-8080-exec-4] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - Loading properties [messages.properties]
2012-09-03 02:59:45,912 [http-bio-8080-exec-4] DEBUG org.springframework.context.support.ReloadableResourceBundleMessageSource - No properties file found for [WEB-INF/i18n/messages_fr] - neither plain properties nor XML
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议吗?我可以将属性文件移动到类路径并相应地更改我的配置,但我宁愿了解发生了什么.
对于开发,我ResourceBundle用来直接从IDE中的resources-directory读取UTF-8编码的属性文件(我在Eclipse的文件属性中设置该文件)(native2ascii用于生产的方式),例如:
menu.file.open.label=&Öffnen...
label.btn.add.name=&Hinzufügen
label.btn.remove.name=&Löschen
Run Code Online (Sandbox Code Playgroud)
由于这会在使用非ASCII字符时导致字符编码问题,我以为我会满意:
ResourceBundle resourceBundle = ResourceBundle.getBundle("messages", Locale.getDefault());
String value = resourceBundle.getString(key);
value = new String(value.getBytes(), "UTF-8");
Run Code Online (Sandbox Code Playgroud)
嗯,它确实适用于小写德语变音符号,但不适用于大写的变音符号,ß也不起作用.这是读取getString(key)的值和转换后的值new String(value.getBytes(), "UTF-8"):
&Löschen => &Löschen
&Hinzufügen => &Hinzufügen
&Ã?ber => &??ber
&SchlieÃ?en => &Schlie??en
&Ã?ffnen... => &??ffnen...
Run Code Online (Sandbox Code Playgroud)
最后三个应该是:
&Ã?ber => &Über
&SchlieÃ?en => &Schließen
&Ã?ffnen... => &Öffnen...
Run Code Online (Sandbox Code Playgroud)
我想我离真相不太远,但我在这里错过了什么?
谷歌发现了类似的东西,但仍然没有答案.
编辑:多一点代码
有两种方法可以将属性文件加载到JSF 2.0中.
faces-config.xml中
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<resource-bundle>
<base-name>com.mkyong.messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
</faces-config>
Run Code Online (Sandbox Code Playgroud)
选项2:本地资源包在本地或仅为指定页面加载属性文件.<f:loadBundle />在页面中声明需要访问messages.properties中的消息的标记.
在这两个中哪一个给了我更好的表现?
假设我使用第一个选项,是否意味着在应用程序启动期间所有捆绑包都被加载或是否是延迟加载?(一经请求)
如果选择第二个选项,是否可能导致每个ViewRoot多次加载bundle?
Java ResourceBundle是工厂类,它在servlet容器中提供单例对象吗?
我的意思是getBundle方法是工厂方法,它总是创建单独的对象?
ResourceBundle myResources =
ResourceBundle.getBundle("MyResources", currentLocale);
Run Code Online (Sandbox Code Playgroud)
假设我有一个页面abc.xhtml,我使用的是f:loadBundle,有1000个用户访问此页面,这是否意味着会创建1000个resouceBundle对象?或者它只是所有页面实例共享的对象?
我的faces-config.xml喜欢下面的内容.
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-
facesconfig_2_0.xsd"
version="2.0">
<application>
<message-bundle>resources.application</message-bundle>
<locale-config>
<default-locale>en</default-locale>
</locale-config>
</application>
</faces-config>
Run Code Online (Sandbox Code Playgroud)
Xhtml文件
<f:loadBundle basename="resources.application" var="msg"/>
Run Code Online (Sandbox Code Playgroud)
我得到以下例外
javax.faces.view.facelets.TagAttributeException: //D:/12c_Workspace/VNPO/WebContent/login.xhtml @9,59 <f:loadBundle basename="resources.application"> Can't find bundle for base name resources.application, locale en
at com.sun.faces.facelets.tag.jsf.core.LoadBundleHandler.apply(LoadBundleHandler.java:233)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:86)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:774)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:100)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:74)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3288)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
at …Run Code Online (Sandbox Code Playgroud) 我有ac#应用程序,我使用visual studio 2013来开发它.在尝试支持i18n时,为每种语言创建了资源文件:
resources.en.resx
resources.fr.resx
resources.es.resx
resources.de.resx and so on...
Run Code Online (Sandbox Code Playgroud)
我想将所有资源文件的KEY(而不是值)更改为更具描述性的内容,例如将"Header.Text"更改为"MainExceptionTitle.Text"目前,我认为无法执行此操作,只能手动更改它每个文件,都非常繁琐.
我查看了zeta资源编辑器项目,但它也只允许编辑值而不是键.
有没有办法做到这一点?
我们在WildFly 8上有一个JSF应用程序,它通过WEB-INF\classes在WAR文件夹中包含德语和英语的消息包以及faces-config.xml将名称映射到它并列出语言环境的配置,使用传统的文本国际化机制.应用程序没有数据库连接,但使用REST服务与第二个应用程序通信.
现在我们需要能够更轻松地更改文本,这意味着不必在更改文本时构建新的WAR文件并进行部署.所以我需要一种机制来将消息包放在WAR之外,同时能够像以前一样在XHTML页面中使用它.
两个可选的要求是更改文本并刷新应用程序中的消息,而不必重新启动应用程序(优先级2),并在WAR中使用默认包,该包将被外部包覆盖(优先级3).
我的想法是使用像Apache commons配置之类的东西来读取Application scoped bean中的属性文件,并在之前使用的EL名称下公开getter.但不知何故,感觉必须重新实现一个现有的机制,这应该更容易,甚至可能只使用Java EE核心.
是否有人以这种方式使用这种机制并且可以指出我对细节的一些示例/描述或者有更好的想法来实现列出的要求?
resourcebundle ×10
java ×6
jsf ×2
jsf-2 ×2
c# ×1
external ×1
faces-config ×1
java-ee ×1
junit ×1
locale ×1
spring ×1
spring-mvc ×1
spring-roo ×1