编辑
对这个答案持保留态度。自从我多年前提出这个问题以来,情况发生了很大变化。我现在建议使用 Lombok 而不是我的 EL 解决方案。出于历史原因留下原始问题。
当我不需要控制对对象内部状态的访问时,我非常厌倦 getter/setter 阻塞我的代码。我仍然必须生成 getter/setter 的唯一真正原因是因为 EL 通过定位方法而不是字段来工作:${myBean.fieldName}
. wherefieldName
指的是方法getFieldName()
。除非找到 getter,否则是否可以扩展 EL Resolver 以仅返回公共字段值?
根据史蒂夫·阿特金森的回答更新:我希望这对其他人有所帮助。请注意我是如何明确检查我仅在 Form 或 Lead 对象上使用此 elresolver 的,这些对象是我的域对象。
public class PublicFieldSupportingELResolver extends ELResolver {
@Override
public Class<?> getCommonPropertyType(ELContext context, Object base) {
if (base instanceof Form || base instanceof Lead) {
try {
context.setPropertyResolved(true);
return base.getClass();
} catch (Exception e) {
context.setPropertyResolved(false);
return null;
}
} else {
context.setPropertyResolved(false);
return null;
}
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
return null;
}
@Override
public Class<?> getType(ELContext context, Object base, Object property) {
if (base instanceof Form || base instanceof Lead) {
try {
Field field = base.getClass().getField((String) property);
context.setPropertyResolved(true);
return field.getType();
} catch (Exception e) {
context.setPropertyResolved(false);
return null;
}
} else {
context.setPropertyResolved(false);
return null;
}
}
@Override
public Object getValue(ELContext context, Object base, Object property) {
if (base instanceof Form || base instanceof Lead) {
try {
Field field = base.getClass().getField((String) property);
Object value = field.get(base);
context.setPropertyResolved(true);
return value;
} catch (Exception e) {
context.setPropertyResolved(false);
return null;
}
} else {
context.setPropertyResolved(false);
return null;
}
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
if (base instanceof Form || base instanceof Lead) {
try {
base.getClass().getField((String) property);
context.setPropertyResolved(true);
return true;
} catch (Exception e) {
context.setPropertyResolved(false);
return false;
}
} else {
context.setPropertyResolved(false);
return false;
}
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value) {
if (base instanceof Form || base instanceof Lead) {
try {
Field field = base.getClass().getField((String) property);
field.set(base, value);
context.setPropertyResolved(true);
} catch (Exception e) {
context.setPropertyResolved(false);
}
} else {
context.setPropertyResolved(false);
}
}
}