1

当我发现未对消息应用 UTF-8 渲染时,我正在对旧 JSF-1.x 项目中的消息/字符串进行国际化。

我在这里遇到了类似的问题:- i18n with UTF-8 encoding properties files in JSF 2.0 appliaction

但这适用于 JSF-2 应用程序,我无法以与那里解释的相同方式注册我的自定义资源包。(显示名称空间不匹配的部署错误。)

需要帮助在 faces-config.xml 中为 JSF-1.x 注册我的自定义资源包。

(我们在那里使用了 message-bundle。但是我不能像在 resource-bundle 标签中那样在 message-bundle 中注册我的 bundle 类)

4

1 回答 1

1

JSF-1.x中,不支持注册我自己的自定义ResourceBundle类。

因此,需要继续创建一个自定义标记<x:loadBundle>,以正确编码对属性文件进行编码。

请参阅Facelets 自定义标签未呈现Tag Library XML在您的web.xml. 然后在你的TagLibrary XML,有这个配置: -

<tag>
            <tag-name>loadBundle</tag-name>
            <handler-class>org.somepackage.facelets.tag.jsf.handler.LoadBundleHandler</handler-class>
</tag>

并扩展您的自定义 LoadBundleHandler 以扩展 TagHandler facelets 类-(代码将与 LoadBundleHandler @相同com.sun.facelets.tag.jsf.core.LoadBundleHandler

现在您可以像我在问题中提到的帖子中那样覆盖 Control 类。所以总的来说你的班级看起来像这样: -

public final class LoadBundleHandler extends TagHandler {


    private static final String BUNDLE_EXTENSION = "properties";    // The default extension for langauge Strings (.properties)

    private static final String CHARSET = "UTF-8";

    private static final Control UTF8_CONTROL = new UTF8Control();  

    private final static class ResourceBundleMap implements Map {
        private final static class ResourceEntry implements Map.Entry {

            protected final String key;

            protected final String value;

            public ResourceEntry(String key, String value) {
                this.key = key;
                this.value = value;
            }

            public Object getKey() {
                return this.key;
            }

            public Object getValue() {
                return this.value;
            }

            public Object setValue(Object value) {
                throw new UnsupportedOperationException();
            }

            public int hashCode() {
                return this.key.hashCode();
            }

            public boolean equals(Object obj) {
                return (obj instanceof ResourceEntry && this.hashCode() == obj
                        .hashCode());
            }
        }

        protected final ResourceBundle bundle;

        public ResourceBundleMap(ResourceBundle bundle) {
            this.bundle = bundle;
        }

        public void clear() {
            throw new UnsupportedOperationException();
        }

        public boolean containsKey(Object key) {
            try {
                bundle.getString(key.toString());
                return true;
            } catch (MissingResourceException e) {
                return false;
            }
        }

        public boolean containsValue(Object value) {
            throw new UnsupportedOperationException();
        }

        public Set entrySet() {
            Enumeration e = this.bundle.getKeys();
            Set s = new HashSet();
            String k;
            while (e.hasMoreElements()) {
                k = (String) e.nextElement();
                s.add(new ResourceEntry(k, this.bundle.getString(k)));
            }
            return s;
        }

        public Object get(Object key) {
            try {
                return this.bundle.getObject((String) key);
            } catch( java.util.MissingResourceException mre ) {
                return "???"+key+"???";
            }
        }

        public boolean isEmpty() {
            return false;
        }

        public Set keySet() {
            Enumeration e = this.bundle.getKeys();
            Set s = new HashSet();
            while (e.hasMoreElements()) {
                s.add(e.nextElement());
            }
            return s;
        }

        public Object put(Object key, Object value) {
            throw new UnsupportedOperationException();
        }

        public void putAll(Map t) {
            throw new UnsupportedOperationException();
        }

        public Object remove(Object key) {
            throw new UnsupportedOperationException();
        }

        public int size() {
            return this.keySet().size();
        }

        public Collection values() {
            Enumeration e = this.bundle.getKeys();
            Set s = new HashSet();
            while (e.hasMoreElements()) {
                s.add(this.bundle.getObject((String) e.nextElement()));
            }
            return s;
        }
    }

    private final TagAttribute basename;

    private final TagAttribute var;


    public LoadBundleHandler(TagConfig config) {
        super(config);
        this.basename = this.getRequiredAttribute("basename");
        this.var = this.getRequiredAttribute("var");
    }


    public void apply(FaceletContext ctx, UIComponent parent)
            throws IOException, FacesException, FaceletException, ELException {
        UIViewRoot root = ComponentSupport.getViewRoot(ctx, parent);
        ResourceBundle bundle = null;
        FacesContext faces = ctx.getFacesContext();
        String name = this.basename.getValue(ctx);
        try {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            if (root != null && root.getLocale() != null) {
                bundle = ResourceBundle.getBundle(name, root.getLocale(), cl, UTF8_CONTROL);
            } else {
                bundle = ResourceBundle
                        .getBundle(name, Locale.getDefault(), cl);
            }
        } catch (Exception e) {
            throw new TagAttributeException(this.tag, null , e);
        }
        ResourceBundleMap map = new ResourceBundleMap(bundle);
        faces.getExternalContext().getRequestMap().put(this.var.getValue(ctx),
                map);
    }



    protected static class UTF8Control extends Control {
        public ResourceBundle newBundle
            (String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
                throws IllegalAccessException, InstantiationException, IOException
        {
            String bundleName = toBundleName(baseName, locale);
            String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION);
            ResourceBundle bundle = null;
            InputStream stream = null;
            if (reload) {
                URL url = loader.getResource(resourceName);
                if (url != null) {
                    URLConnection connection = url.openConnection();
                    if (connection != null) {
                        connection.setUseCaches(false);
                        stream = connection.getInputStream();
                    }
                }
            } else {
                stream = loader.getResourceAsStream(resourceName);
            }
            if (stream != null) {
                try {
                    bundle = new PropertyResourceBundle(new InputStreamReader(stream, UTF8_CONTROL));
                } finally {
                    stream.close();
                }
            }
            return bundle;
        }
    }


}

您甚至可以通过删除此类basename中的属性来跳过配置。<x:loadbundle var="msg basename="resources">basename

于 2013-02-15T08:37:00.863 回答