#java #jsf-2 #views #request #javabeans
#java #jsf-2 #число просмотров #запрос #javabeans
Вопрос:
У меня есть следующее простое представление 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
аннотации and в компоненте и вывести <f:event ...>
из представления, но тогда я не понимаю, почему я вообще должен использовать <f:viewParam>
and <f:metadata>
…
Спасибо
Ответ №1:
JSF просто нужно установить полученный или автоматически созданный ненулевой компонент в вспомогательном компоненте, как вы сказали ему делать by binding
. Вам необходимо предоставить метод установки. Никаких оправданий. Если получатель вернул созданный вручную компонент, будет установлен только тот же компонент. JSF не будет устанавливать автоматически созданное свойство.
Комментарии:
1. Использовал ли я оба? Не очень жаль. Я использую одно или другое, либо
<f:viewParama>
<f:event type="preRenderView">
(который не работает / не работал), поэтому у меня не было другого выбора, кроме как использовать@ManagedProperty
@PostConstruct
(последние аннотации не комментируются!).2. Извините за это, аннотации с комментариями имеют тот же цвет, что и в моей IDE, и я был введен в заблуждение быстрым сканированием кода при недостаточном количестве кофеина в моей крови. Я удалил заметку.
3. Хех, я так и думал. Нет проблем. 🙂 Просто нужен сеттер, хм … спасибо