问题
In JSF 2.0, if a message is not found in the message bundle, then by default, the key is surrounded with ???
. This is a very usable hint during development. However, in my particular case, I really would like that those ???
were not present. I prefer that only the key would be rendered.
E.g. when I do
#{msg.hello}
and the key 'hello' doesn't exist, then the page displays
???hello???
but I would like to show the bare key
hello
The message bundle is loaded in a JSF page as follows:
<f:loadBundle basename="resources.text" var="msg" />
The <f:loadBundle>
tag doesn't seem to have an attribute to manipulate the way values are retrieved from that bundle. Should I overwrite some class or how to intercept the way messages are retrieved from the bundle?
I've found a very interesting article on this: Context Sensitive Resource Bundle entries in JavaServer Faces applications – going beyond plain language, region & variant locales. However, in my case, I just want to omit the ???
. I think this solution is rather complicated. How can I achieve it anyway?
回答1:
The basename
can point to a fullworthy ResourceBundle class. E.g.
<f:loadBundle basename="resources.Text" var="msg" />
with
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);
}
}
You can overridde the bundle message handling in handleGetObject
. JSF by default (by spec) calls getObject()
, catches MissingResourceException
and returns "???" + key + "???"
when caught. You can do it differently.
@Override
protected Object handleGetObject(String key) {
try {
return parent.getObject(key);
} catch (MissingResourceException e) {
return key;
}
}
回答2:
You could also create a simple bean that takes care of the string manipulation. This approach is a lot better if you don't need to remove the default surroundings everywhere but only on a specific place(s). The second function is a lot safer to use, since it also takes care of the case where translation starts and ends with the ???
.
@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;
}
}
Usage:
<h:outputText value="#{localeUtils.getMessage(msg['hello'])}"/>
<h:outputText value="#{localeUtils.getMessage(msg, 'hello')}"/>
来源:https://stackoverflow.com/questions/6451215/how-to-remove-the-surrounding-when-message-is-not-found-in-bundle