3

我有这个 SelectOneMenu:

<h:selectOneMenu value="#{orderController.requestVO.requestSituation}">
    <f:converter converterId="ComboConverter"/>
    <f:selectItems value="#{orderController.requestSituation}" var="requestSituation"
                                                   itemLabel="#{requestSituation.description}" itemValue="#{requestSituation}" />
</h:selectOneMenu>

requestSituation是一个ArrayList填充RequestSituationVO 它正确填充,生成这个HTML:

<select name="j_idt14:j_idt20" size="1">
        <option value="13">Pedido Recusado</option>
    <option value="11">Pedido Validado</option>
    <option value="12" selected="selected">Pedido Confirmado</option>
    <option value="12" selected="selected">Pedido Faturado</option>
</select>

我有这个Converter,这就是我感到困惑的地方,我读了很多书,我知道它必须做什么,但不知道它是如何工作的。

这里是:

@FacesConverter(value = "ComboConverter", forClass = RequestSituationVO.class)
public class ComboConverter implements Converter
{

    private static RequestSituationVO requestSituationVO = new RequestSituationVO();

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value)
    {
        requestSituationVO.setId(Integer.valueOf(value));
        requestSituationVO = (RequestSituationVO) new RequestSituationBO().getRequestSituation(requestSituationVO).toArray()[0];
        return (RequestSituationVO) requestSituationVO;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        requestSituationVO = (RequestSituationVO) value;
        String teste = String.valueOf(requestSituationVO.getId());
        return teste;
    }
}

当我提交我的页面时,我认为SelectOneMenu会自动设置requestSituation方法的值 from requestVO。但是当我提交时,我收到一条Value not valid引用我的SelectOneMenu.

我需要在 my 上设置选定的值,RequestSituationVO以便将其发送到 Business 方法。

4

2 回答 2

10

你的转换器没问题。否则你会得到一个转换错误,比如

'null Converter' 的转换错误设置值'com.example.RequestSituationVO@hashcode'

你有一个验证错误。当对列表中任何可用项目Object#equals()的所选项目的测试未返回时,将抛出此特定项目。trueJSF 正在检查以防止被篡改请求的攻击。在您的特定情况下,这可能有以下原因:

  • 类的equals()方法RequestSituationVO丢失或损坏。
  • #{orderController.requestSituation}显示表单的请求和处理表单提交的请求之间发生了不兼容的变化。

我认为是前者。鉴于您RequestSituationVO具有Integer id唯一标识对象的属性,这应该这样做:

@Override
public boolean equals(Object other) {
    return (other instanceof RequestSituationVO) && (id != null)
        ? id.equals(((RequestSituationVO) other).id)
        : (other == this);
}

@Override
public int hashCode() {
    return (id != null)
        ? (this.getClass().hashCode() + id.hashCode())
        : super.hashCode();
}

如果equals()方法不是问题,那么是后者的原因。这可以通过确保#{orderController.requestSituation}在显示表单和处理表单提交期间返回完全相同的列表来解决。这可以通过将 bean 放在视图范围内而不在 getter 中执行业务逻辑来实现。或者,如果它实际上表示应用程序范围的数据,您可以将其重构为单独的应用程序范围 bean。

也可以看看

于 2012-05-15T17:26:47.300 回答
3

看起来你忘了实现equalsand hashCodein RequestSituation
非常重要,因为 JSF 会将提交的值与所有给定的项目进行比较。

如果你不实现equals,它认为提交的项目不在列表中,
所以它会拒绝它。( The value is not valid.)

于 2012-05-15T17:25:09.943 回答