JSF自定义UISelectOne POSTback错误;验证错误:值无效

时间:2017-05-30 15:00:51

标签: jsf-2

我在Custom UISelectOne组件中遇到问题。我的目的是创建包含自己数据的新自定义组件。所以我在组件的costactor方法中创建了虚拟数据访问,如下所示。当我将控件放在XHTML文件中时,它在页面首次加载时工作正常,但是当我点击HTML页面的子按钮时会出现错误和警告。错误和警告消息如下所示;

顺便说一下,我看到了一些类似的问题。但它们都不是关于自定义控制的,我无法解决我的问题。正如我所说,我想在组件自己的承包商中加载数据。所以我认为我的情况似乎有所不同。

  

)警告:FacesMessage已经入队,但可能没有入队   显示。 sourceId = j_idt6:j_idt7 [严重性=(错误2),   summary =(j_idt6:j_idt7:验证错误:值无效),   detail =(j_idt6:j_idt7:验证错误:值无效)]

所以我的控制和编码器代码:

@Named("ABankAccountList")
@RequestScoped
@FacesComponent(createTag = true, namespace = "http://abank.com.tr/example", tagName = "ABankAccountList", value = "com.abank.customcontrols.ABankAccountList")
public class ABankAccountList extends UISelectOne {



    private List<Account> accounts;

    public ABankAccountList() {

       this.setConverter(new AccountConverter());
        accounts=new ArrayList<Account>();
        Account tempAcc = null;
        for (int i = 5; i < 8; i++) {
            tempAcc = new Account();
            tempAcc.setAccountId(i);
            tempAcc.setAccountNumber(i + "0456-789");
            tempAcc.setCurrencyCode("TRY");
            tempAcc.setIbanNumber("TR-" + i + "-98583213213223");
            accounts.add(tempAcc);

        }

    }   

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

    // After POST Back
    @Override
    public void decode(FacesContext context) {


        super.decode(context);


    }

    @Override
    public void encodeBegin(FacesContext context) throws IOException {

        if (context.isPostback()) 
        {
            return ;

        }

        UISelectItems selectItems = new UISelectItems();

        List<SelectItem> result = new ArrayList<SelectItem>();
        try {

            for (Account account : accounts) {
                SelectItem item = new SelectItem(account, account.getAccountNumber());
                result.add(item);

            }

        } catch (Exception e) {
            // log.error("Failed to create enum list", e);
        }


        getChildren().clear();

        selectItems.setValue(result);
        getChildren().add(selectItems);






    }

    // Render HTML
    @Override
    public void encodeEnd(FacesContext context) throws IOException {


        super.encodeEnd(context);
    }



}

我还有一个Convertet类,如下所示。 当我调试代码时,我注意到postbak之后getAsObject方法触发了两次。我不确定它是否正常?

@FacesConverter(value = "AccountConverter")
public class AccountConverter implements Converter
{

    @Override
    public Object getAsObject(FacesContext context, UIComponent uiComponent, String arg2) 
    {

         ValueExpression vex = context.getApplication().getExpressionFactory()  .createValueExpression(context.getELContext(),       
                 "#{ABankAccountList}", ABankAccountList.class);

         ABankAccountList contoller = (ABankAccountList)vex.getValue(context.getELContext());
         Account rAccount=null;
         for (Account acc : contoller.getAccounts()) {
                if (arg2.toString().equals(acc.getAccountId().toString())) {
                    rAccount = acc;
                }
            }        

            return rAccount;
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object account) {
         Account accctemp=((Account)account);
         Integer accid=accctemp.getAccountId();
         return accid.toString();

    }

}

实际上我不确定我应该在哪里加载数据,而且应该设置转换器类。我理解的是;问题是因为回发之前和之后的数据匹配。但我不知道该怎么办?

最诚挚的问候。

1 个答案:

答案 0 :(得分:0)

您好我找到了解决方案。我已经覆盖了Value Class的equals方法。

@Override
    public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if (obj instanceof Account) 
        {
            Account other = (Account) obj;
            if (other.getAccountId() == this.getAccountId()
                && other.getIbanNumber() == this.getIbanNumber()    
                    )
                return true;
        }
        return false;
    }