Jsf 2 JSF viewAction传递param并设置它,但返回null

Jsf 2 JSF viewAction传递param并设置它,但返回null,jsf-2,primefaces,Jsf 2,Primefaces,JSF2.2 Primefaces 4.0 JBossWildfly 从包含客户列表的页面,并希望每个客户都有一个按钮,用户可以在其中添加项目。 当我点击“新建项目”按钮时,我被重定向到新建项目页面 url中是客户id newItem.jsf;jsessionid=Xw7tdljr9f0atzyET2Fy6_WI?customerId=3 我可以调试新项目bean中的set customer id方法调用时的值为3,nice:) 但是在调试之后,就调用了get customer id方法。。现

JSF2.2
Primefaces 4.0
JBossWildfly

从包含客户列表的页面,并希望每个客户都有一个按钮,用户可以在其中添加项目。 当我点击“新建项目”按钮时,我被重定向到新建项目页面

url中是客户id

newItem.jsf;jsessionid=Xw7tdljr9f0atzyET2Fy6_WI?customerId=3
我可以调试新项目bean中的set customer id方法调用时的值为3,nice:)
但是在调试之后,就调用了get customer id方法。。现在客户id为空:(

我做了一个系统:

18:10:25312信息[stdout](默认任务-9)设置客户id 3

因此,客户id已开始设置…但不知何故已重置为空

customers.xhtml

<ui:define name="content">
<f:metadata>
    <f:viewParam name="customerId" value="#{customerController.customerEnt.id}" />
</f:metadata>
<h:form id="customers" prependId="false" includeViewParams="true">
    <p:dataTable id="dataTable" var="customer"
        value="#{customerController.customers}" rowKey="#{customer.id}"
        styleClass="userDataTableStyle" paginator="true" rows="10"
        selection="#{customerController.selectedCustomers}"
        paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
        lazy="true" rowsPerPageTemplate="10,15,50">
  ... 

        <p:column>
            <p:commandButton ajax="false" value="New Item" action="#{customerController.newItem(customer)}"/>
        </p:column>

    </p:dataTable>

</h:form>
CustomerController.java

@SuppressWarnings("serial")
@ViewScoped
@Named
public class NewItemController implements Serializable {

    private CustomerEnt customerEnt;
    private String customerId;

    @PostConstruct
    public void init() {
        itemEnt = new ItemEnt();

        if (customerId == null) {
            String message = "Bad request. Please use a link from within the system.";
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
            return;
        }

        customerEnt = customerDas.find(Long.parseLong(customerId));

        if (customerEnt == null) {
            String message = "Bad request. Unknown customer.";
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
        }
    }

    public String getCustomerId() {
        return customerId;
    }

    public void setCustomerId(String customerId) {
        this.customerId = customerId;
        System.out.println("Setting customer id " + customerId);
    }
}
@SuppressWarnings("serial")
@SessionScoped
@Named
public class CustomerController implements Serializable {

    private Long customerId;

    public String newItem(CustomerEnt customerEnt) {
        customerId = customerEnt.getId();
        return "newItem?faces-redirect=true&customerId=" + customerId;
    }
正如L-Ray所说,init被调用了两次,所以我在NewItemController中做了如下更改:

        public void init() {
            System.out.println("In init");
        }

        @PostConstruct
        public void postConstruct() {
            itemEnt = new ItemEnt();
            System.out.println("In postConstruct");

        }

    public void loadData() {
            if (customerId == null) {
                String message = "Bad request. Please use a link from within the system.";
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
                return;
            }
        }


public void save() throws Exception {
        try {
            serviceSLSB.save(Long.parseLong(customerId), itemEnt);
            FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_INFO, "Saved!", "Item saved successful");
            facesContext.addMessage(null, m);
            postConstruct();
        } catch (ConstraintViolationException e) {
            itemEnt.setBid(null);
            String errorMessage = getRootErrorMessage(e);
            FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Saving unsuccessful");
            facesContext.addMessage(null, m);
        } catch (Exception e) {
            String errorMessage = getRootErrorMessage(e);
            FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Saving unsuccessful");
            facesContext.addMessage(null, m);
        }
    }
在newItem.xhtml中

<ui:define name="content">
<f:metadata>
    <f:viewParam name="customerId"
        value="#{newItemController.customerId}" />
    <f:viewAction action="#{newItemController.init()}"/>
</f:metadata>
<h:form id="item" includeViewParams="true">
...
<f:metadata>
                <f:viewParam name="customerId"
                    value="#{newItemController.customerId}" />
                <f:viewAction action="#{newItemController.loadData()}"/>
            </f:metadata>
<ui:define name="content">
    <!-- 
    <f:metadata>
         <f:viewParam name="customerId"
             value="#{newItemController.customerId}" />
         <f:viewAction action="#{newItemController.init()}"/>
    </f:metadata>
    -->

    <h:form id="item">
    ...
</ui:define>

但现在我有了一个新问题。。我将为此创建一个单独的问题:)
感谢您的帮助

给定的源代码看起来不错-只有一件事吸引了我的注意:目前,您的NewItemController.init()get被调用了两次

  • as@PostConstruct
  • 通过f:viewAction

如果您仍然调用该方法,您不需要注释,不是吗?

我永远不会理解
f:viewParam
。。。可能您在
CustomerController.newItem()中错过了
includeViewParams=true
?从未在表单上看到过,可能是JSF2.2

我是这样做的:

@ViewScoped
@Named
public class NewItemController implements Serializable
{
    private CustomerEnt customerEnt;

    @ManagedProperty("#{param.customerId}")
    private String customerId;

    @PostConstruct
    public void init()
    {
        if(customerId == null)
        {
            String message = "Bad request. Please use a link from within the system.";
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
            return;
        }

        customerEnt = customerDas.find(Long.parseLong(customerId));

        if(customerEnt == null)
        {
            String message = "Bad request. Unknown customer.";
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
        }
    }

    public String getCustomerId()
    {
        return customerId;
    }

    public void setCustomerId(String customerId)
    {
        this.customerId = customerId;
        System.out.println("Setting customer id " + customerId);
    }
}
和newItem.xhtml

<ui:define name="content">
<f:metadata>
    <f:viewParam name="customerId"
        value="#{newItemController.customerId}" />
    <f:viewAction action="#{newItemController.init()}"/>
</f:metadata>
<h:form id="item" includeViewParams="true">
...
<f:metadata>
                <f:viewParam name="customerId"
                    value="#{newItemController.customerId}" />
                <f:viewAction action="#{newItemController.loadData()}"/>
            </f:metadata>
<ui:define name="content">
    <!-- 
    <f:metadata>
         <f:viewParam name="customerId"
             value="#{newItemController.customerId}" />
         <f:viewAction action="#{newItemController.init()}"/>
    </f:metadata>
    -->

    <h:form id="item">
    ...
</ui:define>

...

customerDas
未在
newItemController.java
中声明,猜测是在缩小代码示例时丢失的?我删除了很多以最小化:@Inject private CustomerService customerDas;这是简单的数据访问服务很酷,很高兴看到它正在工作。您能否将答案标记为“已接受”,以便其他成员和系统正确识别?祝您今天过得愉快。。。L