我知道这个问题现在有点老了,但我遇到了同样的问题并找到了另一个解决方案,我想分享一下:
创建一个自定义 EL-Resolver 并在 jsf 中使用枚举和 java 常量作为对象 el:
<h:graphicImage name="error.png" library="images"
rendered="#{viewController.current.status == Status.ERROR}" />
但在您可以通过这种方式使用枚举之前,您必须执行 3 个步骤。
1.步骤 - 复制该类并通过您的 enumClass 替换“MY_ENUM”(在上面的示例中为“Status”)
public class EnumCache {
private Map<String, Object> propertCache = new HashMap<String, Object>();
private Map<String, Class> baseCache = new HashMap<String, Class>();
private static EnumCache staticEnumCache = null;
public static EnumCache instance() {
if (staticEnumCache == null) { staticEnumCache = new EnumCache(); }
return staticEnumCache;
}
private EnumCache() {
List<Class<?>> classes = new ArrayList<Class<?>>();
classes.add(MY_ENUM.class);
for(Class clazz : classes) {
try {
baseCache.put(clazz.getSimpleName(), clazz);
Method m = clazz.getMethod("values", (Class[]) null);
Enum<?>[] valueList = (Enum[]) m.invoke(null, (Object[]) null);
for (Enum<?> en : valueList) {
propertCache.put(clazz.getSimpleName() + "." + en.name(), en);
}
} catch (Exception e) {
System.err.println(clazz.getSimpleName(), e);
}
}
}
public Object getValueForKey(String key) {
return propertCache.get(key);
}
public Class getClassForKey(String key) {
return baseCache.get(key);
}
}
2。步骤 - 添加此 EnumResolver - 该类会将您的 JSF 表达式映射到缓存中的枚举(步骤 1)
public class MyEnumResolver extends ELResolver {
public Object getValue(ELContext context, Object base, Object property) {
Object result = null;
if (base == null) {
result = EnumCache.instance().getClassForKey(property + "");
} else if (base instanceof Class) {
result = EnumCache.instance().getValueForKey(((Class) base).getSimpleName() + "." + property);
}
if (result != null) {
context.setPropertyResolved(true);
}
return result;
}
public Class<?> getCommonPropertyType(ELContext context, Object base) {
return null;
}
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
return null;
}
public Class<?> getType(ELContext context, Object base, Object property) {
return null;
}
public boolean isReadOnly(ELContext context, Object base, Object property) {
return false;
}
public void setValue(ELContext context, Object base, Object property, Object arg3) {
}
}
3. step - 在 faces-config.xml 中注册 EnumResolver
<faces-config>
<application>
<el-resolver>com.asd.MyEnumResolver</el-resolver>
</application>
</faces-config>
注意:
如果你想以这种方式访问你的 java 常量,你只需要扩展 enumCache 类的构造函数。
这个(untestet)示例应该可以工作:
baseCache.put(CLASS_WITH_CONSTANTS.getSimpleName(), clazz);
for (Field field : CLASS_WITH_CONSTANTS.getDeclaredFields()) {
try {
propertCache.put(CLASS_WITH_CONSTANTS.getSimpleName() + "."
+ field.getName(), field.get(null));
} catch (Exception e) { }
}
希望这个精简但有效的代码可以帮助任何人。
更新
我看到了这些好处:
如果您在 jsf 中使用字符串 (viewController.current.status == 'ERROR_abcdefg'),您可能会拼错该值,并且无法快速识别它。
使用我的解决方案,您在加载 jsf 文件时会出错,因为无法解析枚举。
您可以在源代码中看到“ERROR”是枚举“STATUS”的值。
比较 el 中的两个值时,也会比较枚举的类。
因此,例如 PersonState.ACTIV 与 AccounState.ACTIV 不同。
当我必须将枚举值从 PersonState.ACTIV 更改为 PersonState.ACTIVATED 时,我可以在我的源代码中搜索字符串“PersonState.ACTIV”。搜索“ACTIV”会有更多匹配项。