У меня есть следующее простое представление 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>
Мой боб:
@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 читать здесь?
Примечание. Обходной путь может заключаться в том, чтобы раскомментировать аннотации @ManagedProperty
и @PostConstruct
в бобе и закомментировать <f:event ...>
в представлении, но тогда я не понимаю, почему я должен использовать <f:viewParam>
и <f:metadata>
вообще ...
Спасибо