How to remove the surrounding ??? when message is not found in bundle

梦想与她 提交于 2019-12-28 06:24:46

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!