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

发布于 2024-10-17 08:40:15 字数 1392 浏览 3 评论 0原文

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

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

属性名称是guest。方法是:

  • getGuest;
  • 设置来宾;
  • 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}" />

I have an input (JSF) that should be bound to a property in my bean. This property represents another bean and has an auxiliar method that checks if it's null (I use this method a lot).

The problem is that the binding is failing to get the proper getter and setter. Instead of reading the method that returns the bean, it reads the one that return a boolean value.

The property name is guest. The methods are:

  • getGuest;
  • setGuest;
  • isGuest (checks if guest is null).

JSF is trying to bind the object to isGuest and setGuest, instead of getGuest and setGuest.

I cannot rename isGuest to guestIsNull or something, because that would'nt make to much sense (see the class below).

Finally, my question is: how can I bind this property to the object without renaming my methods? Is it possible?

I also accept suggestions of a better method name (but the meaning must be the same).


Entity

@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}" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

¢好甜 2024-10-24 08:40:15

将方法名称更改为 isGuestNull

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

Change the method name to isGuestNull.

The problem you're seeing is due to the fact that the EL lets you use getFoo or isFoo as the naming style for getter methods that return booleans.

丑疤怪 2024-10-24 08:40:15

不,那不可能。你必须重新命名它们。

另一种方法是添加一个返回涵盖所有情况的枚举的 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'}">

No, that's not possible. You've to rename them.

Another way is to add a single getter returning an enum which covers all cases.

public enum Type {
    GUEST, EMPLOYEE;
}

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

with

<h:something rendered="#{passenger.type == 'GUEST'}">
鹤仙姿 2024-10-24 08:40:15

如果您创建自定义 ELResolver (apidocs)。 elresolvers 在 faces 配置中注册,并且在给定一个定义属性的对象和字符串的情况下,它们负责确定给定属性的值和类型(并且在需要时更改它)。

您可以轻松编写自己的 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; }

}

Binding to any property using any method is possible and quite easy if you create your custom ELResolver (apidocs). elresolvers are registered in faces config, and they are responsible, given an Object and a String defining a property, for determining the value and type of the given properties (and, as the need arises, to change it).

You could easily write your own ELResolver that would only work for your chosen, single type, and use (for example in a switch statement) the specific methods you need to write and read properties. And for other types it would delegate resolving up the resolver chain. It's really easy to do, much easier than it sounds.

But don't do it. The standard naming pattern of properties predates EL by many years. It is part of the JavaBeans™ standard - one of the very few undisputed standards in Javaland, working everywhere - from ant scripts, through spring configuration files to JSF. Seeing methods isPerson and getPerson in one class actually makes me fill uneasy, as it breaks something I always take for granted and can always count on.

If you like DDD and want to have your method's names pure, use an adapter. It's easy, fun, and gives a couple of additional lines, which is not something to sneer at if you get paid for the ammount of code produced:

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; }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文