JSF 2.0 中的 UpdateModelException ClassCastException

发布于 2024-12-11 05:36:06 字数 6305 浏览 0 评论 0 原文

我有一个带有 ui:repeat 标签的 Facelets 页面,该标签输出 HTML 表的行,并且每行接受用户输入。这有效。我还有使用相同页面和中继器输出的第二组数据(只是不同的数据)。支持此页面的支持 bean 是 ConversationScoped。

<ui:repeat value="#{cloneBuilderBean.pageTemplate}" var="row" varStatus="status">
  <tr>
    <td>#{row.label}</td>
    <td><h:inputText value=#{row.value}/></td>
  </tr>
</ui:repeat>

我遇到的问题是当用户单击 h:commandButton“继续”到下一页时。这实际上只是重新显示当前页面,但中继器的集合已更新为一组新的数据。从我的调试来看,我什至没有到达我的操作方法,该方法应该因单击 commandButton 进入下一页而触发。下面的堆栈跟踪也没有显示任何命中我的代码的迹象。关于如何解决此错误有什么想法吗?

javax.faces.component.UpdateModelException: java.lang.ClassCastException
    at javax.faces.component.UIInput.updateModel(UIInput.java:853)
    at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
    at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:525)
    at com.sun.faces.facelets.component.UIRepeat.processUpdates(UIRepeat.java:748)
    at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
    at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassCastException
    at javax.el.ArrayELResolver.setValue(ArrayELResolver.java:257)
    at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
    at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
    at com.sun.el.parser.AstValue.setValue(AstValue.java:197)
    at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:286)
    at org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:74)
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
    at javax.faces.component.UIInput.updateModel(UIInput.java:818)
    ... 41 more

更新:相关的bean代码是这样的:

private int[] part1,part2;
private int[] currentPart; //pointer to part1 or part2
private List<SelectItem> pageTemplate;

public String openItem(String value){
    conversation.begin();

    //database dummy data...
    pageTemplate = new ArrayList(4);
    pageTemplate.add(new SelectItem("Data1"));
    pageTemplate.add(new SelectItem("Data2"));
    pageTemplate.add(new SelectItem("Data3"));
    pageTemplate.add(new SelectItem("Data4"));

    //database dummy data...
    part1 = new int[4];
    for(int i = 0; i < part1.length; i++){
        part1[i] = i+1;
    }
    currentPart = part1;

    return "page2";
}

public String next(){
    //database dummy data...
    part2 = new int[4];
    for(int i = 0; i < part2.length; i++){
        part2[i] = i+2;
    }
    currentPart = part2;
    return "page2";
}

相关的视图代码是:

<ui:repeat value="#{CloneBuilderBean.pageTemplate}" var="row" varStatus="status">
    <tr>
        <td>#{row.value}</td>
        <td width="300">
            <h:inputHidden id="val" value="#{CloneBuilderBean.currentPart[status.index]}" />
            <p:slider for="val" step="1" style="width:90%;" minValue="0" maxValue="7" />
        </td>
    </tr>
</ui:repeat>

<h:commandButton value="display part 2" action="#{CloneBuilderBean.next()}"/>

I have a facelets page with a ui:repeat tag that outputs the rows of an HTML table and each row accepts user input. This works fines. I also have a second set of data that I output using the same page and repeater (just different data). The backing bean supporting this page is ConversationScoped.

<ui:repeat value="#{cloneBuilderBean.pageTemplate}" var="row" varStatus="status">
  <tr>
    <td>#{row.label}</td>
    <td><h:inputText value=#{row.value}/></td>
  </tr>
</ui:repeat>

The problem I have is when the user clicks an h:commandButton to "continue" to the next page. This really just redisplays the current page but the collection of the repeater has been updated to a new set of data. From my debugging, it doesn't look like I ever even get to my action method that should fire as a result of clicking the commandButton to go to the next page. The stack trace below also doesn't show any signs of hitting my code. Any thoughts on how to resolve this error?

javax.faces.component.UpdateModelException: java.lang.ClassCastException
    at javax.faces.component.UIInput.updateModel(UIInput.java:853)
    at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
    at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:525)
    at com.sun.faces.facelets.component.UIRepeat.processUpdates(UIRepeat.java:748)
    at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
    at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassCastException
    at javax.el.ArrayELResolver.setValue(ArrayELResolver.java:257)
    at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
    at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
    at com.sun.el.parser.AstValue.setValue(AstValue.java:197)
    at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:286)
    at org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:74)
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
    at javax.faces.component.UIInput.updateModel(UIInput.java:818)
    ... 41 more

Update: the relevant bean code is this:

private int[] part1,part2;
private int[] currentPart; //pointer to part1 or part2
private List<SelectItem> pageTemplate;

public String openItem(String value){
    conversation.begin();

    //database dummy data...
    pageTemplate = new ArrayList(4);
    pageTemplate.add(new SelectItem("Data1"));
    pageTemplate.add(new SelectItem("Data2"));
    pageTemplate.add(new SelectItem("Data3"));
    pageTemplate.add(new SelectItem("Data4"));

    //database dummy data...
    part1 = new int[4];
    for(int i = 0; i < part1.length; i++){
        part1[i] = i+1;
    }
    currentPart = part1;

    return "page2";
}

public String next(){
    //database dummy data...
    part2 = new int[4];
    for(int i = 0; i < part2.length; i++){
        part2[i] = i+2;
    }
    currentPart = part2;
    return "page2";
}

the relevant view code is:

<ui:repeat value="#{CloneBuilderBean.pageTemplate}" var="row" varStatus="status">
    <tr>
        <td>#{row.value}</td>
        <td width="300">
            <h:inputHidden id="val" value="#{CloneBuilderBean.currentPart[status.index]}" />
            <p:slider for="val" step="1" style="width:90%;" minValue="0" maxValue="7" />
        </td>
    </tr>
</ui:repeat>

<h:commandButton value="display part 2" action="#{CloneBuilderBean.next()}"/>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愁杀 2024-12-18 05:36:06

由:java.lang.ClassCastException引起
在 javax.el.ArrayELResolver.setValue(ArrayELResolver.java:257)

我重现了您的问题。事实证明,#{CloneBuilderBean.currentPart[status.index]} 是使用 Integer 而不是 int 设置的。当我用 Integer[] 替换 int[] 时,它对我有用。

当我尝试在 Tomcat 7.0.19 而不是 Glassfish 3.1.1 上重现您的问题时,我从其 EL 解析器中得到了更清晰的异常:

由以下原因引起:java.lang.ClassCastException:无法将 [java.lang.Integer] 类型的对象添加到 [int] 类型的对象数组
在 javax.el.ArrayELResolver.setValue(ArrayELResolver.java:96)

Caused by: java.lang.ClassCastException
at javax.el.ArrayELResolver.setValue(ArrayELResolver.java:257)

I reproduced your problem. It turns out that #{CloneBuilderBean.currentPart[status.index]} is been set with a Integer instead of an int. It works for me when I replace int[] by Integer[].

When I tried to reproduce your problem on Tomcat 7.0.19 instead of Glassfish 3.1.1, I got a more clear exception from its EL parser:

Caused by: java.lang.ClassCastException: Unable to add an object of type [java.lang.Integer] to an array of objects of type [int]
at javax.el.ArrayELResolver.setValue(ArrayELResolver.java:96)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文