【问题标题】:Deferred EL does not get resolved延迟的 EL 没有得到解决
【发布时间】:2011-07-15 11:22:48
【问题描述】:

我在使用 JSF 时遇到了一些问题。

看起来延迟评估(例如#{bean.property} 没有得到解决。立即评估(例如${bean.property})似乎工作正常。

以下JSF页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1-strict.dtd">
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<f:view>
<html>
<head>
  <title>Hello World</title>
</head>
<body>
  <h:form>
    ${nameBean.name}
    #{nameBean.name}
    <h:outputText value="#{nameBean.name}"/>
  </h:form>
</body>
</html>
</f:view>

我的 web.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
  xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>JSF Test</display-name>
  <context-param>
    <param-name>javax.faces.CONFIG_FILES</param-name>
    <param-value>/WEB-INF/faces-config.xml</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
  </context-param>
  <filter>
    <display-name>Ajax4jsf Filter</display-name>
    <filter-name>ajax4jsf</filter-name>
    <filter-class>org.ajax4jsf.Filter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>ajax4jsf</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
  <login-config>
    <auth-method>BASIC</auth-method>
  </login-config>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

具有以下 maven 依赖项:

<dependency>
  <groupId>jstl</groupId>
  <artifactId>jstl</artifactId>
  <version>1.2</version>
</dependency>
<dependency>
  <groupId>javax.faces</groupId>
  <artifactId>jsf-api</artifactId>
  <version>1.2_12</version>
</dependency>
<dependency>
  <groupId>javax.faces</groupId>
  <artifactId>jsf-impl</artifactId>
  <version>1.2_12</version>
</dependency>
<dependency>
  <groupId>com.sun.facelets</groupId>
  <artifactId>jsf-facelets</artifactId>
  <version>1.1.14</version>
</dependency>

转换为包含以下内容的 HTML 页面:

NameInBean
#{nameBean.name}
#{nameBean.name}

我可能配置错误,但我不知道去哪里找。有人可以帮我吗?

【问题讨论】:

    标签: java jsf maven-2 el


    【解决方案1】:

    让我感到奇怪的是,您正在编写 JSP,但包含 Facelets 库(这是一种更好的 JSF 视图技术)。

    Facelets 允许评估模板文本中的#{} 语法。


    JSP 中的延迟 EL 表达式只允许在支持它们的属性标记中使用(通常是 JavaServer Faces 组件,但可以编写自己的自定义标记库来支持它们)。

    来自JSP 2.2 spec

    模板文本中的表达式只允许使用${} 语法。翻译 如果在模板文本中使用了#{},则会导致错误,除非#{} 通过 向后兼容机制。

    由于您没有使用 deferredSyntaxAllowedAsLiteral 页面指令并且没有收到错误,我猜您的 web.xml 定义了一个默认为 JSP 2.0 或更旧规则的版本您没有通过 FacesServlet 映射处理页面。

    • 检查您的 web.xml 版本(如果您需要更多信息,请说明您的目标服务器和版本)
    • 检查 URL 是否使用 FacesServlet mapping

    【讨论】:

    • 我已将我的 web.xml 添加到原始帖子中。我通过以下 URL 访问我的页面:http://localhost:8080/webproject/getName.faces.
    • @Psy - 我没有看到 web.xml 有任何明显的问题。您在哪个应用服务器/版本上进行测试?
    • 我在 Tomcat 6.0 上运行它。
    【解决方案2】:

    我重新安装了我的 Tomcat 服务器并将我的 pom.xml 修改为:

    <dependency>
      <groupId>org.apache.myfaces.core</groupId>
      <artifactId>myfaces-api</artifactId>
      <version>1.2.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.myfaces.core</groupId>
      <artifactId>myfaces-impl</artifactId>
      <version>1.2.2</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.myfaces.tomahawk</groupId>
      <artifactId>tomahawk</artifactId>
      <version>1.1.6</version>
      <scope>runtime</scope>    
      <exclusions>
        <exclusion>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
        </exclusion>
      </exclusions>    
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
      <scope>runtime</scope>
    </dependency>   
    <dependency>
      <groupId>com.sun.facelets</groupId>
      <artifactId>jsf-facelets</artifactId>
      <version>1.1.11</version>
    </dependency>
    

    现在代码可以工作了。

    【讨论】:

      【解决方案3】:

      我不完全确定,但您需要将 #{nameBean.name} 放入 JSF 组件中。尝试使用&lt;h:outputText value="#{nameBean.name}"/&gt;

      来自a java.net article上的统一表达语言:

      延迟评估是指使用统一 EL 的技术从 JSP 引擎接管评估表达式的责任,并在页面生命周期的适当时间评估表达式。 EL 从 JSP 容器中获得控制权,以便在适当的时间评估表达式。 JSF EL 表达式采用#{defExpr} 的形式。 JSF 表达式以这种方式工作。

      这意味着 JSF 负责评估延迟的表达式,并且只有在将它们添加到 JSF 组件时才会识别它们。直接表达式仍然有效意味着在 JSF 完成渲染响应阶段之后,servlet/JSP 引擎接管并评估这些表达式。因此,您甚至可以使用延迟的表达式生成立即表达式(虽然未测试)。

      【讨论】:

      • 不幸的是,这给了我相同的输出:#{nameBean.name} 而不是 NameInBean
      • 您是否在faces-config.xml 中声明了nameBean
      • 是的,我做到了,${nameBean.name} 从 bean 中检索到正确的名称。其他两个选项都没有。
      【解决方案4】:

      您没有关闭 f:view-Tag - 也许这可能是问题所在?顺便提一句。它不应该跟随 html 标签吗?

      【讨论】:

      • 复制/粘贴时出现问题,我修复了代码示例。
      【解决方案5】:

      您必须使用 Servlet API 2.5 或更高版本。

      您必须更改 web.xml 中的版本

      <web-app 
          xmlns="http://java.sun.com/xml/ns/javaee" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
          version="2.5">
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-30
        相关资源
        最近更新 更多