JSF 2.0 中的 UpdateModelException ClassCastException
我有一个带有 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我重现了您的问题。事实证明,
#{CloneBuilderBean.currentPart[status.index]}
是使用Integer
而不是int
设置的。当我用Integer[]
替换int[]
时,它对我有用。当我尝试在 Tomcat 7.0.19 而不是 Glassfish 3.1.1 上重现您的问题时,我从其 EL 解析器中得到了更清晰的异常:
I reproduced your problem. It turns out that
#{CloneBuilderBean.currentPart[status.index]}
is been set with aInteger
instead of anint
. It works for me when I replaceint[]
byInteger[]
.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: