在JSF中绑定bean属性到元素时出现问题

3

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

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

属性名称是guest。 方法如下:

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

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}" />
3个回答

4

把方法名改成isGuestNull

你遇到的问题是由于EL允许你使用getFoo或者isFoo作为布尔型getter方法的命名风格。


这不是特定于JSF,而是EL实现的。 - BalusC
重命名方法确实可以解决问题,但它会改变其含义。hasGuest 也会改变含义,但更为常见。总之,重命名方法是解决问题的方法。谢谢。 - William Brombal Chinelato

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_)。枚举将强制每个用户手动检查类型。 - William Brombal Chinelato
枚举允许更精细的控制。但如果您不需要这个,那就重命名吧,是的 :) - BalusC

1

使用任何方法绑定到任何属性都是可能的,如果您创建自定义ELResolver(apidocs),那么这将变得非常容易。EL解析器在faces config中注册,它们负责确定给定属性的值和类型(以及必要时更改它),给定一个对象和定义属性的字符串。

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

但不要这样做。属性的标准命名模式早于EL许多年。它是JavaBeans™标准的一部分 - 在Javaland中极少有争议的标准之一,可以在各处工作 - 从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; }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接