Несовместимость editableValueHolder составного компонента с проверкой бина - PullRequest
1 голос
/ 03 января 2012

У меня есть следующий составной компонент:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
  xmlns="http://www.w3.org/1999/xhtml" 
  xmlns:h="http://java.sun.com/jsf/html" 
  xmlns:composite="http://java.sun.com/jsf/composite" 
>
<composite:interface>
  <composite:attribute name="value"/>
  <composite:editableValueHolder name="value" targets="#{cc.clientId}:value"/>
</composite:interface>

<composite:implementation>
  <h:inputText id="value" />
  <h:message for="#{cc.clientId}:value"/>
</composite:implementation>

</html>

И следующий управляемый компонент

import java.util.Date;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.validation.constraints.NotNull;

@ViewScoped
@ManagedBean
public class TestMB {

    @NotNull
    private Date value;

    public String action1() {
        System.out.println("The value is: " + value);
        return null;
    }

    public Date getValue() {
        return value;
    }

    public void setValue(Date value) {
        this.value = value;
    }

}

И следующий пользовательский преобразователь:

import java.util.Date;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter("myCustomConverter")
public class MyCustomConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
        if (value == null || "".equals(value)) {
            return null;
        }
        return new Date();
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object obj) {
        if (obj == null) {
            return null;
        }
        return obj.toString();
    }
}

Иследующая тестовая страница:

<h:body>
  <h:form>
    Enter value: 
    <wui:test value="#{testMB.value}" id="myID">
      <f:converter converterId="myCustomConverter" for="value"/>
    </wui:test>
    <h:commandLink action="#{testMB.action1}" value="submit"/>
  </h:form>
</h:body>

Когда я запускаю веб-приложение, оставляю текстовое поле пустым и нажимаю кнопку подтверждения, никаких ошибок проверки не возникает, и я получаю следующее на консоли Java:

The value is: null

Чтобы сделать вещи более сложными, если я изменю свой составной компонент следующим образом (я добавил значение = "# {cc.attrs.value}" к h: inputText

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
  xmlns="http://www.w3.org/1999/xhtml" 
  xmlns:h="http://java.sun.com/jsf/html" 
  xmlns:composite="http://java.sun.com/jsf/composite" 
>
<composite:interface>
  <composite:attribute name="value"/>
  <composite:editableValueHolder name="value" targets="#{cc.clientId}:value"/>
</composite:interface>

<composite:implementation>
  <h:inputText id="value" value="#{cc.attrs.value}"/>
  <h:message for="#{cc.clientId}:value"/>
</composite:implementation>

</html>

И попробуйтеснова, чтобы отправить форму, когда значение NO установлено, я не вижу никаких ошибок проверки на странице, но я получаю следующее предупреждение в консоли:

INFO: WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
sourceId=myID:value[severity=(ERROR 2), summary=(may not be null), detail=(may not be null)]

Затем, если я пытаюсь повторноснова отправьте форму, действие будет отправлено, даже если поле пустое, и я получу в консоли следующее:

The value is: null

Однако, если я удалю id = "myID" всевсе в порядке!

Наконец: Если я установлю prependId = "false" в моей форме, все в порядке.

Но я не хочу устанавливать prependId = "false", и мне действительно нужно установить идентификатор: (*

...