简体   繁体   English

@PostConstruct中的CDI参数

[英]CDI params in @PostConstruct

I think my question is similar to this but haven't found it to work 我认为我的问题与类似,但尚未发现它可行

  <f:metadata>
  <f:viewParam id="id" name="id" value="#{detailsBean.id}"/>
 </f:metadata>

Why can't I do this with @Named and utilize CDI: 为什么我不能用@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);

}

I'm not able to log the id. 我无法记录身份证。

Of course, @ManagedProperty is incompatible with CDI. 当然,@ ManagedProperty与CDI不兼容。

*****UPDATE***** ***** UPDATE *****

some xhtml: 一些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}"   /> &nbsp;
                <p:commandLink value="Default View" action="#{contactsBean.viewDefault}"  /> &nbsp;
                <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>

more java code: 更多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()));
        }

    }
}

and even more: 甚至更多:

@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());

    }
}

The inputText boxes populate fine. inputText框填充得很好。 But soon as I hit submit it says that the values are null. 但是当我点击提交时,它表示值为空。 This code works perfectly with SessionScope. 此代码与SessionScope完美配合。

WARNING: /admin/index.xhtml @104,109 value="#{detailsBean.detailsContact.name}": Target Unreachable, 'null' returned null javax.el.PropertyNotFoundException: /admin/index.xhtml @104,109 value="#{detailsBean.detailsContact.name}": Target Unreachable, 'null' returned null 警告:/admin/index.xhtml @ 104,109 value =“#{detailsBean.detailsContact.name}”:目标无法访问,'null'返回null javax.el.PropertyNotFoundException:/admin/index.xhtml @ 104,109 value =“#{ detailsBean.detailsContact.name}“:目标无法访问,'null'返回null

I can see that it's calling the EditBean when I select the data table. 我可以看到它在选择数据表时调用EditBean。 It then calls it again when I click the submit button. 然后,当我单击提交按钮时,它再次调用它。

I encountered the exact same problem than you, and solved it by using the external context (containing GET parameters) instead of f:viewParam . 我遇到了与你完全相同的问题,并通过使用外部上下文(包含GET参数)而不是f:viewParam来解决它。

In your @PostConstruct method, just get your parameter with something like @PostConstruct方法中,只需使用类似的方法获取参数

FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();

The lifecycle doesn't allow your approach. 生命周期不允许您的方法。

At first, the bean is created ( constructor ). 首先,创建bean(构造函数)。 After that, there is executed dependency injection which is followed by @PostConstruct method and after that the JSF file is evaluated. 之后,执行依赖注入,然后是@PostConstruct方法,然后评估JSF文件。 And the viewParam is in that file. viewParam在该文件中。 So you have to register another listener which is called after filling view params. 因此,您必须注册另一个在填充视图参数后调用的侦听器。

I have a solution for @RequestScope beans, but if the bean's scope is longer ( like View ) then this method is executed after each request ( including AJAX ) which is not probably desired. 我有一个@RequestScope bean的解决方案,但如果bean的范围更长(如View),则在每个请求(包括AJAX)之后执行此方法,这可能是不可取的。

Use this for request scope beans: 将此用于请求范围bean:

<f:metadata>
   <f:viewParam id="id" name="id" value="#{detailsBean.id}"/>
   <f:event type="preRenderView" listener="#{detailsBean.onLoad}" />
</f:metadata>

For @ViewScope beans I am using this "hack" which works but probably is not best practise. 对于@ViewScope bean,我使用的是“hack”,但它可能不是最佳实践。 It does same thing but probably it isn't the correct approach. 它做同样的事情,但可能它不是正确的方法。

#{detailsBean.onLoad()}
<f:metadata>
   <f:viewParam id="id" name="id" value="#{detailsBean.id}"/>
</f:metadata>

I hope that this is helpful for you. 我希望这对你有所帮助。


EDIT: 编辑:

you are using a lot of AJAX here. 你在这里使用了很多AJAX。 This calls have to land in at least ViewScoped beans. 这些调用必须至少ViewScoped bean。 View Scope is similar to RequestScope , but it takes a quite longer - til the page is left. View Scope与RequestScope类似,但它需要更长的时间 - 直到页面被留下。

But I haven't read it all, there is a lot of code and if the ViewScope doesn't help then maybe you should provide the small piece of problematic code to be chance there to find and focus on the real problem. 但我还没有完全阅读,有很多代码,如果ViewScope没有帮助,那么也许你应该提供一小段有问题的代码,以便有机会找到并专注于真正的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM