在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