在h:selectOneMenu中使用JSF Converter会导致验证错误:值无效

时间:2012-05-15 16:57:47

标签: jsf converter

我有这个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>

requestSituationArrayList,内容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设置requestVO方法的值。但是当我提交时,我会收到一条消息Value not valid,引用我的SelectOneMenu

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

2 个答案:

答案 0 :(得分:10)

你的转换器很好。否则你会得到类似

的转换错误
  

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

您有验证错误。如果所选项目的Object#equals()测试未对列表中的任何可用项目返回true,则会抛出此特定项目。 JSF正在检查以防止被篡改的请求发起攻击。在您的特定情况下,这可能有以下原因:

  • 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。

另见

答案 1 :(得分:3)

您似乎忘了在equals中实施hashCodeRequestSituation 这是非常重要,因为JSF会将提交的值与所有给定的项目进行比较。

如果您未实施equals,则认为提交的项目不在列表中, 所以它拒绝它。 (The value is not valid.