Tôi biết câu hỏi này là một chút cũ bây giờ, nhưng tôi đã có cùng một vấn đề và tìm thấy một giải pháp, mà tôi muốn chia sẻ:
Tạo Custom EL-Resolver và enums sử dụng và java hằng số là các đối tượng trong jsf el:
<h:graphicImage name="error.png" library="images"
rendered="#{viewController.current.status == Status.ERROR}" />
Nhưng trước khi bạn có thể sử dụng enums theo cách này bạn phải thực hiện 3 bước.
1. bước - Sao chép lớp này và thay thế "MY_ENUM" qua enumClass của bạn (trong ví dụ trên nó sẽ là "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. Bước - thêm EnumResolver này - Đây lớp sẽ lập bản đồ biểu hiện JSF của bạn để enum trong bộ nhớ cache (bước 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. bước - đăng ký EnumResolver trong faces-config.xml
<faces-config>
<application>
<el-resolver>com.asd.MyEnumResolver</el-resolver>
</application>
</faces-config>
LƯU Ý: Nếu bạn muốn truy cập hằng java bạn theo cách này, bạn chỉ cần phải mở rộng các nhà xây dựng của lớp enumCache. Ví dụ này (chưa thử) nên hoạt động:
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) { }
}
Hy vọng mã giảm nhưng mã làm việc này có thể giúp bất kỳ ai.
Cập nhật
tôi thấy lợi ích này:
Nếu bạn sử dụng chuỗi trong JSF (viewController.current.status == 'ERROR_abcdefg'), bạn có thể đánh sai giá trị và không nhận ra nó quá nhanh. Với giải pháp của tôi, bạn sẽ gặp lỗi khi tải tệp jsf, vì không thể giải quyết enum.
Bạn có thể thấy trong mã nguồn "ERROR" là giá trị của "STATUS" enum.
Khi bạn so sánh hai giá trị trong el, lớp của các enums cũng sẽ được so sánh. Vì vậy, ví dụ PersonState.ACTIV không giống như AccounState.ACTIV.
Khi tôi phải thay đổi giá trị enum của tôi từ PersonState.ACTIV thành PersonState.ACTIVATED tôi có thể tìm kiếm chuỗi "PersonState.ACTIV" trong mã nguồn của tôi. tìm kiếm "ACTIV" sẽ có nhiều kết quả phù hợp hơn.
Chuỗi so sánh được đánh giá như gọi equals() phương pháp hay như so sánh bằng cách tham khảo? – user3663882