【发布时间】:2015-06-21 11:02:29
【问题描述】:
我正在尝试通过反射从 JSF 页面的支持 bean 访问某些字段的值。问题是,当我使用 getter 时,我得到了正确的值,但是当我使用必要字段的 get(obj) 方法时,我总是得到一个 null 值返回。
获取beanObject:
ELContext elcontext = FacesContext.getCurrentInstance().getELContext();
Object beanObject = FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elcontext, null, beanName);
要在不使用 getter 的情况下获取字段值,我执行以下操作:
List<Field> fields = new ArrayList<Field>();
ParamsBuilder.getAllFields(fields, beanClass);
for(Field field: fields) {
field.setAccessible(true);
System.out.println(field.getName() + ": " + field.get(beanObject)); //just to see if it works
}
getAllFields 方法有这个实现:
public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
for (Field field: type.getDeclaredFields()) {
fields.add(field);
}
if (type.getSuperclass() != null) {
fields = getAllFields(fields, type.getSuperclass());
}
return fields;
}
要使用 getter 获取值,我执行以下操作:
private ClassX getValue(Object beanObject, Class<?> beanClass) throws Exception {
Method getter = beanClass.getDeclaredMethod("myMethod",(Class<?>[]) null);
return (ClassX)getter.invoke(beanObject, (Object[])null);
}
我可以进一步提到的是,我尝试访问的字段是用 @Inject 注释注入的,但我不认为这是问题,因为其他实例字段(未注入)会受到同样的影响。
通常我会使用 getter,但我在这里尝试做的事情会对我正在开发的应用程序产生全局影响,这意味着返回并修改所有受影响的类以提供 getter 是最后的解决方案。此外,这个应用程序会不断地修改和扩展,我不想冒其他开发人员不提供 getter 的机会,这会导致严重的问题。
谢谢!
【问题讨论】:
-
Java 被滥用最多的 API 反射很多时候只是特定于框架的。如果不是真的需要,请避免使用它。
-
如果是通过注入的方式,您如何获取 beanObject,它可能已被代理,因此您可能无法获得任何字段值。
-
我以获取 beanObject 的方式进行了编辑,我认为您使用代理是正确的。有什么办法可以克服吗?
标签: java jsf reflection cdi managed-bean