在JSF 2.0中,如果在消息包中找不到消息,那么默认情况下,键被???
包围。这是开发过程中非常有用的提示。然而,在我的特殊情况下,我真的希望那些???
不在场。我更喜欢只渲染关键帧。
例如,当我进行时
#{msg.hello}
如果"你好"键不存在,则页面显示
你好
但我想展示一下裸钥匙
你好
消息包加载在JSF页面中,如下所示:
<f:loadBundle basename="resources.text" var="msg" />
<f:loadBundle>
标记似乎没有一个属性来操作从该bundle中检索值的方式。我应该重写一些类吗?或者如何拦截从捆绑包中检索消息的方式?
我发现了一篇非常有趣的文章:JavaServerFaces应用程序中的上下文敏感资源捆绑条目——超越了普通语言、区域和;变体区域设置。然而,在我的情况下,我只想省略???
。我认为这个解决方案相当复杂。无论如何,我怎样才能做到这一点?
basename
可以指向一个完整的ResourceBundle
类。例如
<f:loadBundle basename="resources.Text" var="msg" />
带有
package resources;
public class Text extends ResourceBundle {
public Text() {
setParent(getBundle("resources.text", FacesContext.getCurrentInstance().getViewRoot().getLocale()));
}
@Override
public Enumeration<String> getKeys() {
return parent.getKeys();
}
@Override
protected Object handleGetObject(String key) {
return parent.getObject(key);
}
}
您可以在handleGetObject
中重写捆绑包消息处理。JSF默认(根据规范)调用getObject()
,捕获MissingResourceException
,并在捕获时返回"???" + key + "???"
。你可以用不同的方式来做。
@Override
protected Object handleGetObject(String key) {
try {
return parent.getObject(key);
} catch (MissingResourceException e) {
return key;
}
}
您还可以创建一个简单的bean来处理字符串操作。如果你不需要到处删除默认环境,而只需要在特定的地方删除,这种方法会更好。第二个函数使用起来要安全得多,因为它还处理翻译以???
开始和结束的情况。
@ApplicationScoped
@Named
public class LocaleUtils {
public String getMessage(String s) {
return clearMessage(s);
}
public Object getMessage(ResourceBundle propertyResourceBundle, String key) {
try {
return propertyResourceBundle.getObject(key);
}
catch (MissingResourceException e) {
return clearMessage(key);
}
}
private static String clearMessage(String s) {
String clearMessage = s;
String prefix = "???", suffix = "???";
if (s != null && s.startsWith(prefix) && s.endsWith(suffix)) {
s = s.substring(prefix.length());
clearMessage = s.substring(0, s.length() - suffix.length());
}
return clearMessage;
}
}
用法:
<h:outputText value="#{localeUtils.getMessage(msg['hello'])}"/>
<h:outputText value="#{localeUtils.getMessage(msg, 'hello')}"/>