将JSF inputText绑定到HashMap并不起作用

时间:2014-09-08 18:50:54

标签: jsf jsf-2 map el

我正在尝试将多个inputText字段绑定到HashMap<Integer, String>。但它并没有为HashMap赋予任何价值。

这是JSF页面。

<ui:repeat  value="#{questionBean.question.answerCollection}" var="answer">                
    <h:inputText  value="#{questionBean.newComments[answer.answerId]}"></h:inputText>
    <br/>
    <h:commandButton value="Add Comment">
                    <f:ajax event="click" listener="#{questionBean.makeComment(answer)}"></f:ajax>
    </h:commandButton>
</ui:repeat>

这是支持bean的相关部分。

private Map<Integer, String> newComments = new HashMap<Integer, String>();
...

public void makeComment(Answers answer) throws Exception {
    String username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();

    Users user = userFacade.getUserByUsername(username);

    Comments comment = new Comments();

    for(Integer key: newComments.keySet()){
        throw new Exception("Answer ID IS :"+key);
        // It doesn't throw any exception in here.
        // The map is empty.
    }        

    String commentContent = newComments.get(answer.getAnswerId());
    if(commentContent == null){
        throw new Exception("Content Is NULL");
        // It throws exception here.
    }

    comment.setCommentContent(newComments.get(answer.getAnswerId()));
    comment.setDateCreated(new java.sql.Date(Calendar.getInstance().getTimeInMillis()));
    comment.setAnswerId(answer);
    comment.setUserId(user);
    commentFacade.create(comment);
}

此代码可能有什么问题?

1 个答案:

答案 0 :(得分:2)

主要的错误是没有告诉<f:ajax>处理输入字段。其execute事件默认为@this,表示“当前组件”。因此,使用此构造,只会处理<h:commandButton>(即,其操作将被解码,排队和调用)。

因此,通过明确告诉它处理整个表单来相应地修复它:

<f:ajax execute="@form" ... />

下一个(潜在的)错误依赖于EL实现,但截至目前,所有这些错误都不支持泛型。 Map<K, V>只会被视为Map,而不会对键和值进行任何隐式/自动转换。在EL中,数值隐式解释为Long。在您的特定情况下,Map将填充Long个密钥而不是Integer个密钥,可能会在迭代时导致ClassCastException。如果您相应地修改模型以使用Long而不是Integer,那么此问题也应该得到解决。

私人地图newComments = new HashMap();


对于具体问题

无关,在前端使用java.sql.*模型是一个非常糟糕的主意。而是在数据库端使用它。