7

编辑

对这个答案持保留态度。自从我多年前提出这个问题以来,情况发生了很大变化。我现在建议使用 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);
        }
    }
}
4

2 回答 2

6

如果您不想在 Java Bean 上编写/生成 getter 和 setter 方法,则可以使用Project Lombok中的@Getter/@Setter注释。

于 2013-01-30T17:58:31.710 回答
3

是的。Jsf 的可扩展性很强,几乎所有东西都可以扩展或替换。

自定义解析器的一个很好的例子是here

这家伙正在使用它来填充数据库查询中的下拉列表。我敢肯定,您可以使用类似的技术来基于公共字段而不是公共 get/set 方法进行解析。

于 2013-01-30T18:00:32.273 回答