JSF 2: предполагается, что свойство bean-компонента записано вместо read? - PullRequest
0 голосов
/ 12 октября 2011

У меня есть следующее простое представление 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> вообще ...

Спасибо

1 Ответ

2 голосов
/ 12 октября 2011

JSF просто нужно установить полученный или автоматически созданный ненулевой компонент в компоненте поддержки, как вы сказали, чтобы сделать это с помощью binding. Вы должны предоставить метод установки. Никаких оправданий. Если получатель вернул созданный вручную компонент, будет установлен точно такой же компонент. JSF не будет устанавливать автоматически созданный.

...