Прослушиватель Primefaces selectOneMenu не вызывается с объектами, отличными от строк

Я реализую веб-приложение, используя Jsf 2.0 и Primefaces 3.2. Я заметил это неожиданное поведение: у меня есть selectOneMenu и commandButton, как показано ниже.

<p:selectOneMenu id="selsel" value="#{bean.myObj}">
  <f:selectItems value="#{bean.myObjList}" />
</p:selectOneMenu>
<p:commandButton id="btnid" value="Ok" actionListener="#{bean.updateSelectValues()}" />

Что происходит, так это то, что если myObj не является String, метод updateSelectValues не вызывается. Я вообще не вижу никаких исключений или ошибок, это просто не вызывается. Вот поддерживающий компонент:

private List<MyObj> myObjList;
private MyObj myObj;
// getters and setters

public void updateSelectValues() {
  System.out.println(this.myObj);
}

Код для myObj:

public class MyObj implements Serializable {

  private static final long serialVersionUID = 1L;

  private String param1;
  private int param2;

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("MyObj [param1=");
    builder.append(this.param1);
    builder.append(", param2=");
    builder.append(this.param2);
    builder.append("]");
    return builder.toString();
  }

}

person loscuropresagio    schedule 15.05.2012    source источник


Ответы (1)


Это потому, что HTML и HTTP не понимают объекты Java. Все объекты Java преобразуются в String, когда HTML должен быть создан JSF. Все параметры HTTP-запроса, которые являются String, должны быть преобразованы обратно в объект Java, когда отправленные данные формы должны быть обработаны JSF.

Что касается вашей конкретной проблемы, если вы добавили <h:message>, <h:messages> или PrimeFaces, эквивалентные форме (а также обновили ее при отправке ajax), вы должны были заметить ошибку преобразования для «нулевого конвертера». Также, если вы обращали внимание на журнал сервера, вы также должны были увидеть предупреждение о необработанном сообщении.

Вам необходимо создать собственный Converter, который преобразует между MyObj и его уникальным представлением String. Например:

@FacesConverter(forClass=MyObj.class)
public class MyObjConverter implements Converter {

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object valueToRender) {
        // Convert MyObj to its unique String representation.
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        // Convert String to MyObj.
    }

}

Обычно эти объекты уже хранятся в какой-либо базе данных или отображаются по их идентификатору. Затем вы используете именно этот идентификатор как уникальное String представление.

person BalusC    schedule 15.05.2012