无法将#{cc}参数传递给EL函数?

时间:2016-04-08 17:01:49

标签: function jsf parameter-passing el composite-component

我定义了一个JSF复合组件,相关部分如下所示。 更新:改进了使用Kukeltje推荐的JSF 2.2命名空间声明的示例,但问题仍然存在。

/resources/functiontest/functiontest.xhtml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:composite="http://xmlns.jcp.org/jsf/composite"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
>
<composite:interface>
    <composite:attribute name="value" type="java.util.Date"/>
    <composite:attribute name="timeZone" type="java.util.TimeZone"/>
    <composite:attribute name="update" type="java.lang.String"/>
</composite:interface>

<composite:implementation>
    <div id="#{cc.clientId}">
        clientId class=#{cc.clientId['class'].name}<br/>
        clientId=#{cc.clientId}<br/>
        value=#{cc.attrs.value}<br/>
        timeZone=#{cc.attrs.timeZone}<br/>
        update=#{cc.attrs.update}<br/>
        <br/>

        WORKS - fn:toLowerCase - #{fn:toLowerCase("hellOOOOOO")}<br/>
        WORKS - whoName = #{myBean.user}<br/>
        WORKS - fn:toUpperCase1 = #{fn:toUpperCase(myBean.user)}<br/>
        WORKS - fn:toUpperCase2 = #{fn:toUpperCase(myBean.toString())}<br/>
        WORKS - fn:toUpperCase3 = #{fn:toUpperCase(myBean['class'].simpleName)}<br/>
        FAILS - fn:toUpperCase4 = #{fn:toUpperCase(cc.clientId['class'].name)}<br/>
        FAILS - fn:toUpperCase5 = #{fn:toUpperCase(cc.clientId)}<br/>
        FAILS - fn:toUpperCase6 = #{fn:toUpperCase(cc.attrs.value.toString())}<br/>
        FAILS - fn:toUpperCase7 = #{fn:toUpperCase(cc.attrs.update)}<br/>
    </div>
</composite:implementation>
</html>

/src/FunctionTestBean.java

import java.util.Date;
import java.util.TimeZone;

import javax.faces.bean.ManagedBean;

@ManagedBean(name="myBean")
public class FunctionTestBean
{
    public String getUser() { return "UserX"; }
    @Override public String toString() { return "toString method output"; }
    private Date now = new Date();
    public Date getNow() { return now; }
    public TimeZone getTimeZone() { return TimeZone.getDefault(); }
}

/testFunctionPage.xhtml (使用模板 - 从JSF 2.2.5开始不工作)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:composite="http://xmlns.jcp.org/jsf/composite"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
    xmlns:fntest="http://xmlns.jcp.org/jsf/composite/functiontest"
>

<ui:composition template="/template/PublicPageTemplate.xhtml">
<ui:define name="body">
    Function test:<br/>
    <ui:repeat var="loopVar" value='#{"a,b,c".split(",")}'>
        LoopVar=#{loopVar}<br/>
        <fntest:functiontest id="tst2" value="#{myBean.now}" timeZone="#{myBean.timeZone}" update="UpdateOrDontUpdate"/>
    </ui:repeat>

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

/template/PublicPageTemplate.xhtml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
</h:head>
<h:body>

<div style="padding-left:5%; padding-right:5%;">
    <ui:insert name="body">DEFAULT BODY!</ui:insert>
</div>
</h:body>
</html>

/testFunctionPageWithHBody.xhtml (使用h:body - WORKS!)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:composite="http://xmlns.jcp.org/jsf/composite"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
    xmlns:fntest="http://xmlns.jcp.org/jsf/composite/functiontest"
>

<h:head>
</h:head>
<h:body>
    Function test:<br/>
    <ui:repeat var="loopVar" value='#{"a,b,c".split(",")}'>
        LoopVar=#{loopVar}<br/>
        <fntest:functiontest id="tst2" value="#{myBean.now}" timeZone="#{myBean.timeZone}" update="UpdateOrDontUpdate"/>
    </ui:repeat>

</h:body>
</html>

似乎尝试将cc。*的任何部分传递给函数失败,即使它们显然只是打印出值。我已经尝试过JSTL函数和我自己的函数。这是错误:

javax.el.ELException: Function 'fn:toUpperCase' not found

我最好的猜测是使用我没有学到的cc有限制,我希望有人可以阐明它们是什么以及发生了什么。这似乎已在JSF 2.2.5中引入;所有变体都适用于JSF 2.2.1到2.2.4。

这是一些额外的奇怪行为。如果我先加载testFunctionPage.xhtml,则会失败。如果我加载testFunctionPageWithHBody.xhtml,它会成功(如预期的那样)。然后,如果我加载testFunctionPage.xhtml,它现在将成功,并将继续这样做,直到重新启动Web服务器(Tomcat)!

修改: 我运行的环境是Windows 7,Java 1.7.0_80,Tomcat 7.0.68及其版本的EL,JSF Mojarra 2.2.8-14,jstl 1.2,Eclipse Mars.2(4.5.2)。< / p>

0 个答案:

没有答案