Проблема с привязкой свойства bean-компонента к элементу в JSF

У меня есть ввод (JSF), который должен быть привязан к свойству в моем компоненте. Это свойство представляет собой другой bean-компонент и имеет вспомогательный метод, проверяющий, является ли он нулевым (я часто использую этот метод).

Проблема в том, что привязка не может получить правильный геттер и сеттер. Вместо того, чтобы читать метод, который возвращает bean-компонент, он читает тот, который возвращает логическое значение.

Имя свойства — guest. Методы:

  • получитьГость;
  • установитьГость;
  • isGuest (проверяет, является ли гость нулевым).

JSF пытается связать объект с isGuest и setGuest вместо getGuest и setGuest.

Я не могу переименовать 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}" />

person William Brombal Chinelato    schedule 14.02.2011    source источник


Ответы (3)


Измените имя метода на isGuestNull.

Проблема, которую вы видите, связана с тем, что EL позволяет вам использовать getFoo или isFoo в качестве стиля именования для методов получения, которые возвращают логические значения.

person Matt Ball    schedule 14.02.2011
comment
Кстати, это делает не JSF, а EL. - person BalusC; 14.02.2011
comment
Переименование метода работает, но меняет его смысл. hasGuest также меняет значение, но становится более привычным. Что ж, одно можно сказать наверняка: метод переименовывается. Спасибо. - person William Brombal Chinelato; 15.02.2011

Нет, это невозможно. Вы должны переименовать их.

Другой способ — добавить один геттер, возвращающий перечисление, охватывающее все случаи.

public enum Type {
    GUEST, EMPLOYEE;
}

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

с участием

<h:something rendered="#{passenger.type == 'GUEST'}">
person BalusC    schedule 14.02.2011
comment
Да, переименование - единственный выход. С другой стороны, перечисление для меня не лучший вариант, потому что isGuest предназначен для скрытия реализации (if null). Перечисление заставит каждого пользователя проверять тип вручную. - person William Brombal Chinelato; 15.02.2011
comment
Enums позволяет осуществлять более тонкий контроль. Но если вам это не нужно, то просто переименовать, да :) - person BalusC; 15.02.2011

Привязка к любому свойству с помощью любого метода возможна и довольно проста, если вы создадите собственный ELResolver (apidocs). elresolvers прописаны в конфиге Faces, и они отвечают, учитывая Объект и Строку, определяющую свойство, за определение значения и типа данных свойств (и, при необходимости, их изменение).

Вы можете легко написать свой собственный 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; }

}
person fdreger    schedule 15.02.2011