Параметры CDI в @PostConstruct
Я думаю, что мой вопрос похож на Этот , но не нашел его для работы
<f:metadata>
<f:viewParam id="id" name="id" value="#{detailsBean.id}"/>
</f:metadata>
Почему я не могу сделать это с @Named и использовать CDI:
@Named
@RequestScoped
public class DetailsBean {
private Contacts detailsContact;
@EJB
ContactsFacade contactsEJB;
private int id;
public DetailsBean() {
System.out.println("details bean called");
}
@PostConstruct
public void onLoad() {
detailsContact = contactsEJB.find(id);
}
Я не могу зарегистрировать идентификатор.
Конечно, @ManagedProperty несовместим с CDI.*****обновление* * * * *
Некоторые xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="../template.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:f="http://java.sun.com/jsf/core">
<ui:define name="head">
<f:metadata>
<f:viewParam name="paginator" value="#{contactsBean.contactsTablePaginator}"/>
<f:viewParam name="rows" value="#{contactsBean.contactsTableRows}"/>
</f:metadata>
</ui:define>
<ui:define name="content">
<p:growl id="growl" showDetail="true"/>
<p:panel id="contactsPanel" >
<h:form id ="contactsForm">
<p:dataTable id="contactsTable" value="#{contactsBean.contacts}" selection="#{detailsBean.detailsContact}" var="contacts" widgetVar="contactsTable"
selectionMode="single" rowSelectListener="#{contactsBean.rowSelect}" rowUnselectListener="#{contactsBean.rowUnSelect}"
onRowUnselectUpdate="detailsForm" onRowSelectUpdate="detailsForm"
paginator="#{contactsBean.contactsTablePaginator}" rows="#{contactsBean.contactsTableRows}" rowsPerPageTemplate="5,10,15,25,50,100"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search:" />
<p:inputText id="globalFilter" onkeyup="contactsTable.filter()" style="width:150px" />
</p:outputPanel>
</f:facet>
<p:column filterStyle="display:none" filterBy="#{contacts.name}" headerText="Name" style="width:200px">
<h:outputText value="#{contacts.name}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.street}" headerText="Street" style="width:280px">
<h:outputText value="#{contacts.street}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.city}" headerText="City" style="width:150px">
<h:outputText value="#{contacts.city}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.state}" headerText="State" style="width:50px">
<h:outputText value="#{contacts.state}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.zip}" headerText="Zip" style="width:100px">
<h:outputText value="#{contacts.zip}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.country}" headerText="Country" style="width:150px">
<h:outputText value="#{contacts.country}" />
</p:column>
<p:column filterStyle="display:none" filterBy="#{contacts.sent}" headerText="Sent" style="width:50px">
<h:outputText value="#{contacts.sent}" />
</p:column>
</p:dataTable>
<p:ajaxStatus >
<f:facet name="start">
<h:graphicImage value="../resources/images/ajax-loader-bar.gif" />
</f:facet>
<f:facet name="complete">
<h:graphicImage value="../resources/images/ajax-loader-bar-still.gif" />
</f:facet>
<f:facet name="default">
<h:graphicImage value="../resources/images/ajax-loader-bar-still.gif" />
</f:facet>
</p:ajaxStatus>
<br />
<p:commandLink value="View All" action="#{contactsBean.viewAll}" />
<p:commandLink value="Default View" action="#{contactsBean.viewDefault}" />
<p:commandLink value="Advanced Search" action="search?faces-redirect=true" />
<br />
</h:form>
<br />
</p:panel>
<br />
<br />
<h:form id="detailsForm">
<p:panel id="detailsPanel" visible="#{detailsBean.visible}" >
<h:panelGrid id="detailsPanelGrid" cellpadding="2" cellspacing="2" columns="3" >
<h:outputText value="Name :" />
<p:inputText id="name" value="#{detailsBean.detailsContact.name}" style="width:400px" />
<p:message for="name" />
<h:outputText value="Email :" />
<p:inputText id="email" value="#{detailsBean.detailsContact.email}" style="width:400px" validatorMessage="Must be a valid email address. EX: test@test.com" >
<f:validateRegex pattern="[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z0-9]+"/>
<p:ajax event="blur" update="emailMsg" />
</p:inputText>
<p:message id="emailMsg" for="email" />
<h:outputText value="Street :" />
<p:inputText id="street" value="#{detailsBean.detailsContact.street}" style="width:400px" />
<p:message for="street" />
<h:outputText value="City :" />
<p:inputText id="city" value="#{detailsBean.detailsContact.city}" style="width:400px" />
<p:message for="city" />
<h:outputText value="State :" />
<p:inputText id="state" value="#{detailsBean.detailsContact.state}" style="width:400px" validatorMessage="Length is greater than 2" >
<f:validateLength maximum="2" />
<p:ajax event="blur" update="stateMsg" />
</p:inputText>
<p:message id="stateMsg" for="state" />
<h:outputText value="Country :" />
<p:inputText id="country" value="#{detailsBean.detailsContact.country}" style="width:400px" />
<p:message for="country" />
<h:outputText value="Phone :" />
<p:inputText id="phone" value="#{detailsBean.detailsContact.phone}" style="width:400px"/>
<p:message for="phone" />
<h:outputText value="Guests :" />
<p:inputText id="guests" value="#{detailsBean.detailsContact.guests}" style="width:400px"/>
<p:message for="guests" />
<h:outputText value="Arrival :" />
<p:calendar id="arrival" value="#{detailsBean.detailsContact.arrival}" showOn="button" />
<p:message for="arrival" />
<h:outputText value="Departure :" />
<p:calendar id="departure" value="#{detailsBean.detailsContact.departure}" showOn="button" />
<p:message for="departure" />
<h:outputText value="Message :" />
<p:inputTextarea id="message" effectDuration="30" style="width:400px;height:100px;" value="#{detailsBean.detailsContact.message}" />
<p:message for="message" />
<h:outputText value="Departure :" />
<p:calendar id="inserted" value="#{detailsBean.detailsContact.inserted}" showOn="button"/>
<p:message for="inserted" />
<h:outputText value="Sent :" />
<h:selectBooleanCheckbox id="sent" value="#{detailsBean.detailsContact.sent}" />
<p:message for="sent" />
<br />
</h:panelGrid>
<p:commandButton value="Submit" action="#{detailsBean.updateContactDetails}" update="contactsForm, growl, stateMsg" />
<p:commandButton value="Close" action="#{detailsBean.handleClose}" update="contactsForm, detailsForm" />
</p:panel>
</h:form>
</ui:define>
</ui:composition>
Еще код java:
package com.atlanticpkg.view.beans;
import com.atlanticpkg.model.entities.Contacts;
import com.atlanticpkg.util.FacesUtils;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
@Named(value = "detailsBean")
@RequestScoped
public class EditBean {
private Contacts detailsContact;
private boolean visible = false;
@Inject
ContactsBean contactsBean;
public EditBean() {
}
@PostConstruct
public void onLoad() {
}
public void handleClose() {
this.setVisible(false);
this.setDetailsContact(new Contacts());
}
public void updateContactDetails() {
try {
contactsBean.getContactsEJB().edit(detailsContact);
FacesUtils.addMessage(detailsContact.getName() + " was updated successfully!");
} catch (Exception e) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", e.toString()));
}
}
}
И даже больше:
@Named(value = "contactsBean")
@RequestScoped
public class ContactsBean {
@Inject
EditBean editBean;
@EJB
private ContactsFacade contactsEJB;
private List<Contacts> contacts = new ArrayList<Contacts>();
private boolean contactsTablePaginator = true;
private int contactsTableRows = 10;
private Contacts selectedContact = new Contacts();
public ContactsBean() {
}
@PostConstruct
public void onLoad() {
updateContactsList();
}
public String viewDefault() {
contactsTablePaginator = true;
contactsTableRows = 10;
return "index?faces-redirect=true&includeViewParams=true";
}
public String viewAll() {
contactsTablePaginator = false;
contactsTableRows = 100;
return "index?faces-redirect=true&includeViewParams=true";
}
public void updateContactsList() {
contacts.clear();
contacts = contactsEJB.findAll();
}
public void rowSelect(SelectEvent event) {
editBean.setVisible(true);
editBean.setDetailsContact((Contacts) event.getObject());
}
public void rowUnSelect(UnselectEvent event) {
editBean.setVisible(false);
editBean.setDetailsContact(new Contacts());
}
}
Входные текстовые поля заполняются нормально. Но как только я нажимаю submit, он говорит, что значения равны нулю. Этот код отлично работает с SessionScope.
Предупреждение: / admin / index.xhtml @104,109 value= " #{detailsBean.detailsContact.name}": цель недостижима,' null ' возвращает null класса javax.эль.PropertyNotFoundException: / admin / index.xhtml @104,109 value= " #{detailsBean.detailsContact.name}": цель недостижима,' null ' возвращает null
Я вижу, что он вызывает EditBean, когда я выбираю таблицу данных. Затем он вызывает его снова, когда я нажимаю кнопку Отправить.
2 ответа:
Жизненный цикл не допускает вашего подхода.
Сначала создается Боб (конструктор). После этого выполняется инъекция зависимостей, за которой следует Метод
@PostConstruct
, а затем вычисляется файл JSF. ИviewParam
находится в этом файле. Таким образом, вы должны зарегистрировать еще один прослушиватель, который вызывается после заполнения параметров просмотра.У меня есть решение для
@RequestScope
бобов, но если область Боба больше (например, представление), то этот метод выполняется после каждого запроса ( включая AJAX), что, вероятно, нежелательно.Используйте это для бобов области запроса:
<f:metadata> <f:viewParam id="id" name="id" value="#{detailsBean.id}"/> <f:event type="preRenderView" listener="#{detailsBean.onLoad}" /> </f:metadata>
Для
@ViewScope
бобов я использую этот "хак", который работает, но, вероятно, не является лучшей практикой. Он делает то же самое, но, вероятно, это не правильный подход.#{detailsBean.onLoad()} <f:metadata> <f:viewParam id="id" name="id" value="#{detailsBean.id}"/> </f:metadata>
Я надеюсь, что это полезно для вас.
Редактировать:
Вы используете здесь много AJAX. Этот вызов должен приземлиться по крайней мере в
ViewScoped
бобах. Область видимости похожа наRequestScope
, но она занимает довольно много времени. дольше-до тех пор, пока страница не останется.Но я не читал всего, есть много кода, и если ViewScope не помогает, то, возможно, вам следует предоставить небольшой фрагмент проблемного кода, чтобы иметь шанс найти и сосредоточиться на реальной проблеме.