Jasper
Jasper

Reputation: 2176

Deferred EL does not get resolved

I'm having some problems with JSF.

It look like deferred evaluations (eg. #{bean.property} do not get resolved. Immediate evaluations (eg. ${bean.property}) seem to work fine.

The following JSF page:

<!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>

My web.xml looks like this:

<?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>

With the following maven dependencies:

<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>

Translates to an HTML page containing:

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

I probably misconfigured something, but I don't know where to look. Can someone help me?

Upvotes: 1

Views: 4892

Answers (5)

Munkhbayar
Munkhbayar

Reputation: 1

You have to use Servlet API 2.5 or later.

You have to change version in your 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">

Upvotes: 0

Jasper
Jasper

Reputation: 2176

I reinstalled my Tomcat server and modified my pom.xml to:

<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>

And now the code works.

Upvotes: 1

McDowell
McDowell

Reputation: 108909

It strikes me as odd that you are writing JSPs but include the Facelets library (which is a better view technology for JSF).

Facelets allow the evaluation of #{} syntax within template text.


Deferred EL expressions in JSPs are only allowed in attribute tags that support them (typically JavaServer Faces components, but it is possible to write your own custom tag libraries to support them).

From the JSP 2.2 spec:

Only the ${} syntax is allowed for expressions in template text. A translation error will result if #{} is used in template text unless #{} is turned off via a backwards compatibility mechanism.

Since you aren't using the deferredSyntaxAllowedAsLiteral page directive and aren't getting an error, I would guess that your web.xml defines a version that defaults to JSP 2.0 or older rules and that you are not processing the page via the FacesServlet mapping.

  • Check your web.xml version (state your target server and version if you need more info)
  • Check that the URL uses the FacesServlet mapping

Upvotes: 1

jiai
jiai

Reputation: 181

You don't close the f:view-Tag - perhaps this might be the problem? Btw. shouldn't it follow to the html tag?

Upvotes: 0

Thomas
Thomas

Reputation: 88727

I'm not entirely sure but you'd need to put the #{nameBean.name} into a JSF component. Try using <h:outputText value="#{nameBean.name}"/>.

From a java.net article on the unified expression language:

Deferred evaluation means that the technology using the unified EL takes over the responsibility of evaluating the expression from the JSP engine and evaluates the expression at the appropriate time during the page lifecycle. The EL takes control from the JSP container to evaluate the expression at the appropriate time. JSF EL expressions take the form of #{defExpr}. JSF expressions work in this way.

This implies that JSF is responsible to evaluate the deferred expressions and it will recognize them only if they are added to a JSF component. That the immediate expressions still work implies that after JSF is done with the render response phase the servlet/JSP engine takes over and evaluatas those expressions. Thus you might even be able to generate immediate expressions using deferred ones (not tested though).

Upvotes: 0

Related Questions