JSF 2:bean 的属性假定为写入而不是读取?
我有以下简单视图 main.xhtml
,请求 URL 类似于:
http://localhost:8080/myproj/main.jsf?pq=2
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
template="/templating/layout-2col.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="pq" value="#{pqHome.id}" required="true">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
<f:event type="preRenderView" listener="#{pqHome.init}" />
</f:metadata>
</ui:define>
...
<ui:define name="content-right">
<h:form>
<rich:panel>
<f:facet name="header">
Menu
</f:facet>
<rich:tabPanel binding="#{pqHome.tabPanel}">
</rich:tabPanel>
</rich:panel>
</h:form>
</ui:define>
</ui:composition>
My bean:
@ManagedBean
@RequestScoped
public class PqHome implements Serializable
{
@Inject
private PqService pqService;
//@ManagedProperty(value="#{param.pq}")
private Integer id;
private Prequalification instance;
@Inject
private PqPartnerListQuery pplq;
private List<Partner> partners;
private UITabPanel tabPanel;
private List<UIComponent> tabs;
//@PostConstruct
public void init()
{
System.out.println("ID is " + id);
instance = pqService.findSingleInstance(id);
partners = pplq.getItemsForPq(id);
System.out.println("Building tab manually...");
// RF way...
FacesContext fc = FacesContext.getCurrentInstance();
Application application = FacesContext.getCurrentInstance().getApplication();
tabPanel = (UITabPanel)application.createComponent(UITabPanel.COMPONENT_TYPE);
tabPanel.setSwitchType(SwitchType.client);
tabs = tabPanel.getChildren();
for ( Partner partner : partners )
{
Company co = partner.getCompany();
String companyName = co.getName();
UITab tab = (UITab)application.createComponent(UITab.COMPONENT_TYPE);
//tab.setTitle(companyName);
tab.setName(companyName);
tab.setId(co.getDndType());
tabs.add(tab);
}
String firstTabName = partners.get(0).getCompany().getName();
System.out.println("First tab name = " + firstTabName);
tabPanel.setActiveItem(firstTabName);
}
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public Prequalification getInstance()
{
return instance;
}
public UITabPanel getTabPanel()
{
return tabPanel;
}
}
当请求上述页面时,我收到一条错误消息:
An Error Occurred:
/main.xhtml @221,53 binding="#{pqHome.tabPanel}": The class 'de.mycomp.myproj.beans.PqHome' does not have a writable property 'tabPanel'.
+- Stack Trace
javax.el.PropertyNotWritableException: /main.xhtml @221,53 binding="#{pqHome.tabPanel}": The class 'de.mycomp.myproj.beans.PqHome' does not have a writable property 'tabPanel'.
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
at com.sun.faces.application.ApplicationImpl.createComponentApplyAnnotations(ApplicationImpl.java:1897)
at com.sun.faces.application.ApplicationImpl.createComponent(ApplicationImpl.java:1109)
at org.jboss.as.weld.webtier.jsf.ForwardingApplication.createComponent(ForwardingApplication.java:122)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.createComponent(ComponentTagHandlerDelegateImpl.java:511)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:157)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at org.richfaces.view.facelets.html.BehaviorsAddingComponentHandlerWrapper.applyNextHandler(BehaviorsAddingComponentHandlerWrapper.java:55)
...
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.jboss.as.web.NamingValve.invoke(NamingValve.java:57)
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:49)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:154)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:667)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951)
at java.lang.Thread.run(Unknown Source)
为什么 JSF 假定选项卡面板 EL binding="#{pqHome.tabPanel}"
可以在此处写入/可写?有没有办法解决这个问题,那就是告诉 JSF 阅读这里?
注意:解决方法是取消注释 bean 中的 @ManagedProperty
和 @PostConstruct
注释,并取消注释
和
...
谢谢
I have the following simple view main.xhtml
, the request URL would be something like:
http://localhost:8080/myproj/main.jsf?pq=2
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
template="/templating/layout-2col.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="pq" value="#{pqHome.id}" required="true">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
<f:event type="preRenderView" listener="#{pqHome.init}" />
</f:metadata>
</ui:define>
...
<ui:define name="content-right">
<h:form>
<rich:panel>
<f:facet name="header">
Menu
</f:facet>
<rich:tabPanel binding="#{pqHome.tabPanel}">
</rich:tabPanel>
</rich:panel>
</h:form>
</ui:define>
</ui:composition>
My bean:
@ManagedBean
@RequestScoped
public class PqHome implements Serializable
{
@Inject
private PqService pqService;
//@ManagedProperty(value="#{param.pq}")
private Integer id;
private Prequalification instance;
@Inject
private PqPartnerListQuery pplq;
private List<Partner> partners;
private UITabPanel tabPanel;
private List<UIComponent> tabs;
//@PostConstruct
public void init()
{
System.out.println("ID is " + id);
instance = pqService.findSingleInstance(id);
partners = pplq.getItemsForPq(id);
System.out.println("Building tab manually...");
// RF way...
FacesContext fc = FacesContext.getCurrentInstance();
Application application = FacesContext.getCurrentInstance().getApplication();
tabPanel = (UITabPanel)application.createComponent(UITabPanel.COMPONENT_TYPE);
tabPanel.setSwitchType(SwitchType.client);
tabs = tabPanel.getChildren();
for ( Partner partner : partners )
{
Company co = partner.getCompany();
String companyName = co.getName();
UITab tab = (UITab)application.createComponent(UITab.COMPONENT_TYPE);
//tab.setTitle(companyName);
tab.setName(companyName);
tab.setId(co.getDndType());
tabs.add(tab);
}
String firstTabName = partners.get(0).getCompany().getName();
System.out.println("First tab name = " + firstTabName);
tabPanel.setActiveItem(firstTabName);
}
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public Prequalification getInstance()
{
return instance;
}
public UITabPanel getTabPanel()
{
return tabPanel;
}
}
When requesting the above page I get an error saying:
An Error Occurred:
/main.xhtml @221,53 binding="#{pqHome.tabPanel}": The class 'de.mycomp.myproj.beans.PqHome' does not have a writable property 'tabPanel'.
+- Stack Trace
javax.el.PropertyNotWritableException: /main.xhtml @221,53 binding="#{pqHome.tabPanel}": The class 'de.mycomp.myproj.beans.PqHome' does not have a writable property 'tabPanel'.
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
at com.sun.faces.application.ApplicationImpl.createComponentApplyAnnotations(ApplicationImpl.java:1897)
at com.sun.faces.application.ApplicationImpl.createComponent(ApplicationImpl.java:1109)
at org.jboss.as.weld.webtier.jsf.ForwardingApplication.createComponent(ForwardingApplication.java:122)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.createComponent(ComponentTagHandlerDelegateImpl.java:511)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:157)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at org.richfaces.view.facelets.html.BehaviorsAddingComponentHandlerWrapper.applyNextHandler(BehaviorsAddingComponentHandlerWrapper.java:55)
...
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.jboss.as.web.NamingValve.invoke(NamingValve.java:57)
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:49)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:154)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:667)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951)
at java.lang.Thread.run(Unknown Source)
Why does JSF assume the tab panel EL binding="#{pqHome.tabPanel}"
to be written/writable here? Is there a way to fix this, that is tell JSF to read here?
Note: The workaround would be to uncomment the @ManagedProperty
and @PostConstruct
annotations in the bean and outcomment the <f:event ...>
in the view, but then I don't see why I should be using <f:viewParam>
and <f:metadata>
at all...
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
JSF 只需要在支持 bean 中设置获取的或自动创建的非 null 组件,就像您通过
绑定
告诉它的那样。您需要提供一个 setter 方法。没有任何借口。如果 getter 返回手动创建的组件,则将设置完全相同的组件。 JSF 不会设置自动创建的。JSF just needs to set the obtained or auto-created non-null component in the backing bean as you told it to do by
binding
. You need to provide a setter method. No excuses. If the getter returned a manually created component, just the very same component will be set. JSF won't set the auto-created one.