【问题标题】:With EL, is it possible to do field access on beans rather than getters/setters?使用 EL,是否可以对 bean 而不是 getter/setter 进行字段访问?
【发布时间】:2023-04-02 22:10:01
【问题描述】:

编辑

对这个答案持保留态度。自从我多年前提出这个问题以来,情况发生了很大变化。我现在建议使用 Lombok 而不是我的 EL 解决方案。出于历史原因留下了最初的问题。


当我不需要控制对对象内部状态的访问时,我非常厌倦 getter/setter 阻塞我的代码。我仍然必须生成 getter/setter 的唯一真正原因是因为 EL 通过定位方法而不是字段来工作:${myBean.fieldName}。其中fieldName 指的是方法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);
        }
    }
}

【问题讨论】:

  • 警告:这不一定适用于代理 bean(例如 CDI)。
  • 是的,真的不应该再这样做了

标签: jsf el getter-setter field-accessors


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 如果我替换了 faces-config 中的 el-resolver 元素,我将无法使用默认元素。有什么方法可以在不替换默认解析器的情况下添加一个额外的解析器?
    • @JonathanS.Fisher 是的,如果能回答这个问题,我们将不胜感激
    • 查看第一篇文章的编辑 :)
    猜你喜欢
    • 1970-01-01
    • 2013-07-26
    • 2011-09-06
    • 2014-10-08
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多