【问题标题】:Problem binding a bean property to an element in JSF将 bean 属性绑定到 JSF 中的元素的问题
【发布时间】:2011-02-14 18:07:29
【问题描述】:

我有一个应该绑定到我的 bean 中的属性的输入 (JSF)。这个属性代表另一个 bean,并有一个辅助方法来检查它是否为空(我经常使用这种方法)。

问题是绑定无法获得正确的 getter 和 setter。它不是读取返回 bean 的方法,而是读取返回布尔值的方法。

属性名称是guest。方法有:

  • getGuest;
  • setGuest;
  • isGuest(检查 guest 是否为空)。

JSF 正在尝试将对象绑定到 isGuestsetGuest,而不是 getGuestsetGuest

我不能将 isGuest 重命名为 guestIsNull 之类的,因为这没有多大意义(请参阅下面的课程)。

最后,我的问题是:如何在不重命名方法的情况下将此属性绑定到对象?有可能吗?

我也接受更好的方法名称的建议(但含义必须相同)。


实体

@Entity
public class Passenger {

    private Employee employee;
    private Guest guest;

    public Passenger() {
    }

    @Transient
    public boolean isEmployee() {
        return null != this.employee;
    }

    @Transient
    public boolean isGuest() {
        return null != this.guest;
    }

    @OneToOne
    public Employee getEmployee() {
        return this.employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    @OneToOne
    public Guest getGuest() {
        return this.guest;
    }

    public void setGuest(Guest guest) {
        this.guest = guest;
    }

}

JSF

<h:inputText value="#{passenger.employee}" />
<h:inputText value="#{passenger.guest}" />

【问题讨论】:

    标签: jsf binding naming-conventions entity javabeans


    【解决方案1】:

    将方法名称更改为isGuestNull

    您看到的问题是由于 EL 允许您使用 getFoo isFoo 作为返回布尔值的 getter 方法的命名样式。

    【讨论】:

    • 顺便说一下,不是 JSF 专门这样做,而是 EL。
    • 重命名方法确实有效,但它改变了它的含义。 hasGuest 也改变了意思,但它更常用一些。好吧,有一件事是肯定的:重命名方法就是方法。谢谢。
    【解决方案2】:

    不,这是不可能的。您必须重命名它们。

    另一种方法是添加一个 getter,返回一个涵盖所有情况的枚举。

    public enum Type {
        GUEST, EMPLOYEE;
    }
    
    public Type getType() {
        return guest != null ? Type.GUEST
             : employee != null ? Type.EMPLOYEE
             : null;
    }
    

    <h:something rendered="#{passenger.type == 'GUEST'}">
    

    【讨论】:

    • 是的,重命名是唯一的方法。另一方面,枚举对我来说不是一个好的选择,因为 isGuest 旨在隐藏实现(if null)。枚举将强制每个用户手动检查类型。
    • 枚举允许更细粒度的控制。但如果你不需要这个,那么只需重命名,是的:)
    【解决方案3】:

    如果您创建自定义 ELResolver (apidocs),则可以使用任何方法绑定到任何属性并且非常容易。 elresolver 在 faces config 中注册,它们负责在给定定义属性的 Object 和 String 的情况下确定给定属性的值和类型(并根据需要进行更改)。

    您可以轻松编写自己的 ELResolver,它只适用于您选择的单一类型,并使用(例如在 switch 语句中)您需要编写和读取属性的特定方法。对于其他类型,它将委托解析解析器链。这真的很容易做到,比听起来容易得多。

    但不要这样做。属性的标准命名模式比 EL 早了很多年。它是 JavaBeans™ 标准的一部分——Java 领域中为数不多的无可争议的标准之一,它无处不在——从 ant 脚本、spring 配置文件到 JSF。在一个类中看到方法 isPerson 和 getPerson 实际上让我感到不安,因为它破坏了我一直认为理所当然并且总是可以依靠的东西。

    如果您喜欢 DDD 并希望您的方法名称纯净,请使用适配器。它简单、有趣,并且提供了几行额外的代码,如果您因生成的代码量而获得报酬,这不是什么可笑的:

    public class MyNotReallyBean {
    
      public String checkName() { ... }
      public String lookUpLastName() { ... }
      public String carefullyAskAboutAge() { ... }
    
      public class BeanAdapter {
         public String getName() { return checkName(); }
         public String getLastName() { return lookUpLastName(); }
         public String getAge() { return carefullyAskAboutAge(); }
      }
      private static BeanAdapter beanAdapter = new BeanAdapter();
    
      private BeanAdapter getBeanAdapter(){ return beanAdapter; }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      • 2011-12-31
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 2016-10-11
      • 2011-02-23
      相关资源
      最近更新 更多