【问题标题】:JSF Passing Bean to View FailingJSF 传递 Bean 来查看失败
【发布时间】:2014-08-20 13:57:39
【问题描述】:

我正在尝试编写一个简单的 JSF 页面,该页面最初包含两个子视图/包含,并将支持 bean 传递给其中一个包含,因为包含是可重用的(并且可能在更大的应用程序中包含不止一次) .

这是相关代码:

page1.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:pf="http://primefaces.org/ui"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    template="templates/template1.xhtml">

    <ui:define name="subheader">
        Person Details
    </ui:define>

    <ui:define name="bodyContent">
        <h:form>
            <c:forEach items="#{page1Bean.blockNames}" var="blockName">
                <c:choose>
                    <c:when test="#{blockName} eq 'block1'">
                        <ui:include src="block1.xhtml" >
                            <ui:param name="bean" value="#{page1Bean.myBean}"/>
                        </ui:include>
                    </c:when>
                    <c:otherwise>
                        <ui:include src="#{blockName}.xhtml" />
                    </c:otherwise>
                </c:choose>
            </c:forEach>
            <pf:commandButton value="Ajax Button" action="#{page1Bean.ajaxSubmit()}"/>
        </h:form>

    </ui:define>
</ui:composition>

block1.xhtml

<ui:composition 
    xmlns="http://www.w3.org/1999/xhtml"
    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:p="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:pf="http://primefaces.org/ui">

    <h3>This is the first block</h3>
    <h:panelGrid columns="3" style="margin-bottom:10px" cellpadding="5">

        <pf:outputLabel for="firstName" value="Nombre:" />
        <pf:inputText id="firstName" value="#{bean.firstName}" />
        <h:message id="firstNameMessage" for="firstName" />

    </h:panelGrid>
</ui:composition>

Page1Bean.java

package com.views.prototype;

import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;

@ManagedBean
public class Page1Bean {

    private List<String> blockNames;

    private Block1Bean myBean;

    public Page1Bean() {
        blockNames = new ArrayList<String>();

        blockNames.add("block2");
        blockNames.add("block1");

        myBean = new Block1Bean();
    }

    public void ajaxSubmit() {
    }

    @SuppressWarnings("unchecked")
    public static <T> T findBean(String beanName) {
        FacesContext context = FacesContext.getCurrentInstance();
        return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
    }

    public List<String> getBlockNames() {
        return blockNames;
    }

    public void setBlockNames(List<String> blockNames) {
        this.blockNames = blockNames;
    }

    public Block1Bean getMyBean() {
        return myBean;
    }

    public void setMyBean(Block1Bean myBean) {
        this.myBean = myBean;
    }
}

Block1Bean.java

package com.views.prototype;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class Block1Bean {
    private String firstName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Override
    public String toString() {
        return "Block1Bean [firstName=" + firstName + "]";
    }   
}

页面呈现正常,但是当我点击提交时,我得到:

value="#{bean.firstName}":目标不可达,标识符“bean”解析为空

据我所知,我使用的语法与这些示例的解决方案相同:

Reusing the same page multiple times

Passing the backing bean as a parameter to a Facelet include

关于我哪里出错了有什么想法吗?

【问题讨论】:

    标签: java jsf jsf-2


    【解决方案1】:

    问题原来是 JSTL 和 JSF 之间的冲突,正如几个线程所指出的:

    JSTL c:choose c:when not working in a JSF page

    Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work

    所以我重写了循环不使用 JSTL,它摆脱了原始问题中的直接问题:

            <ui:repeat var="blockName" value="#{page1Bean.blockNames}" varStatus="status">
                <ui:fragment rendered="#{blockName == 'block1'}">
                    <ui:include src="#{page1Bean.theBlockName}" >
                        <ui:param name="bean" value="#{page1Bean.myBean}"/>
                    </ui:include>
                </ui:fragment>
    
                <ui:fragment rendered="#{blockName != 'block1' }">
                    <ui:include src="block2.xhtml" />
                </ui:fragment>
    
            </ui:repeat>
    

    (这在功能上不等同于损坏的预期用途,但关键是它不使用 JSTL)。

    【讨论】:

      【解决方案2】:

      这可能是因为您将请求范围的 bean 传递到其他页面。一旦请求完成,bean 就不再存在。尝试对您的 bean 使用更大的范围,例如视图。它应该可以正常工作。

      @ManagedBean
      @ViewScoped
      public class Block1Bean {
      
      }
      

      否则,您将不得不使用 keepAlive 等功能来扩展请求范围。

      【讨论】:

      • 我实际上尝试将范围设置为 SessionScoped 只是为了排除这个问题,但我仍然遇到同样的问题。到目前为止,我似乎已经将问题缩小到与使用 JSTL 标记有关的问题,因为没有
      • 或许this thread可以帮到你
      • 谢谢,我刚刚看到我们有几个类似的线程,这似乎是另一个 JSF/JSTL 不兼容问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 2013-05-08
      • 1970-01-01
      • 2013-02-23
      • 2014-01-21
      • 2012-08-10
      • 2016-01-01
      相关资源
      最近更新 更多