我想要实现的是 UTF-8 编码的 JSF 验证和转换器消息(消息包)。另外,我想要标签等的自定义资源包(资源包)。
我成功地创建和使用了自定义资源包,但是我在定义消息包时遇到了问题。
我在 src/ 目录下有以下结构:
- com.example.i18n.resources
- FacesMsgs.properties
- FacesMsgs_de.properties
- UTF8FacesMsgs.java
- Msgs.properties
- Msgs_de.properties
- UTF8Msgs.java
Faces-config.xml 片段:
<application>
<message-bundle>com.example.i18n.resources.UTF8FacesMsgs</message-bundle>
<resource-bundle>
<base-name>com.example.i18n.resources.UTF8Msgs</base-name>
<var>msg</var>
</resource-bundle>
<locale-config>
<default-locale>de</default-locale>
</locale-config>
</application>
在我的实现中,我遵循了此处给出的说明: JSF 中的国际化与 UTF-8 编码的属性文件
这些是结果类:
public class ResourceBundleWrapper extends ResourceBundle {
public ResourceBundleWrapper(ResourceBundle parent) {
setParent(parent);
}
@Override
protected Object handleGetObject(String key) {
return parent.getObject(key);
}
@Override
public Enumeration<String> getKeys() {
return parent.getKeys();
}
}
编码控制.java
public class EncodingControl extends Control {
private String encoding;
private String extension;
public EncodingControl(String encoding, String extension) {
this.encoding = encoding;
this.extension = extension;
}
@Override
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, 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, encoding));
} finally {
stream.close();
}
}
return bundle;
}
}
UTF8FacesMsgs.java
public class UTF8FacesMsgs extends ResourceBundleWrapper {
public UTF8FacesMsgs() {
super(ResourceBundle.getBundle("com.example.i18n.resources.FacesMsgs",
FacesContext.getCurrentInstance().getViewRoot().getLocale(),
new EncodingControl("UTF-8", "properties"));
}
}
UTF8Msgs.java
public class UTF8Msgs extends ResourceBundleWrapper {
public UTF8Msgs() {
super(ResourceBundle.getBundle("com.example.i18n.resources.Msgs",
FacesContext.getCurrentInstance().getViewRoot().getLocale(),
new EncodingControl("UTF-8", "properties"));
}
}
结果行为:
资源包配置似乎没有问题:使用默认的 UTF8Msgs.java 并且页面上的所有标签都成功呈现。另一方面,消息包的行为是完全不同的,尽管所有的配置都是一样的:当验证失败时(提交按钮触发验证)我得到 MissingResourceException - 不使用默认的 UTF8FacesMsgs.java 并且 UTF8FacesMsgs_de.java 是预期的。
引入更改的行为:
当我像这样配置 faces-config.xml 时(直接使用属性文件,而不是 java 类):
<application>
<message-bundle>com.example.i18n.resources.FacesMsgs</message-bundle>
<resource-bundle>
<base-name>com.example.i18n.resources.UTF8Msgs</base-name>
<var>msg</var>
</resource-bundle>
<locale-config>
<default-locale>de</default-locale>
</locale-config>
</application>
并删除 FacesMsgs_de.properties 一切运行没有问题。所以 - 使用默认属性文件,而不使用默认 java 文件。
有人知道消息包配置有什么问题吗?