在Tomcat 6.0.24中使用EL 2.2

18
使用JSF 2,您应该能够做到这一点:
<h:commandButton action="#{myBean.myAction(myParameter)}"/>

然后调用动作方法,传递参数(假设它是一个整数):

@ManagedBean
@SessionScoped
public class MyBean {
    ...
    public String myAction(Integer myParameter) {
        // do something
        return null;
    }
    ...
}

这在 Glassfish v3 上完美运作。然而,在 Tomcat 上不行,你会收到一个 ELException 通知解析错误。

Caused by: javax.el.ELException: Error Parsing: ...

现在,使用EL 2.2的记录方法和Glassfish的实现可以替换Tomcat lib目录中的el-api jar来使其工作,但是我仍然遇到相同的错误,没有运气。 Tomcat真的让我感到沮丧! JSF2应该更容易!
Maven POM 片段:
<repositories>
  <repository>
    <id>sun</id>
    <url>http://download.java.net/maven/2/</url>
  </repository>
  <repository>
    <id>jboss</id>
    <url>http://repository.jboss.com/maven2/</url>
  </repository>
</repositories>
...
  <dependency>
    <groupId>javax.el</groupId>
    <artifactId>el-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
  </dependency>

  <dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>el-impl</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
  </dependency>

更多信息。

这是部分堆栈跟踪,看起来它仍在使用Apache EL实现,而不是我放入lib中的实现。我完全删除了Tomcat附带的现有el-api.jar,是否还需要删除某个el-impl.jar,以防止其覆盖某些内容?

Was expecting one of:
    "}" ...
    "." ...
    "[" ...
    ">" ...
    "gt" ...
    "<" ...
    "lt" ...
    ">=" ...
    "ge" ...
    "<=" ...
    "le" ...
    "==" ...
    "eq" ...
    "!=" ...
    "ne" ...
    "&&" ...
    "and" ...
    "||" ...
    "or" ...
    "*" ...
    "+" ...
    "-" ...
    "/" ...
    "div" ...
    "%" ...
    "mod" ...

    at org.apache.el.parser.ELParser.generateParseException(ELParser.java:2142)
    at org.apache.el.parser.ELParser.jj_consume_token(ELParser.java:2024)
    at org.apache.el.parser.ELParser.DeferredExpression(ELParser.java:113)
    at org.apache.el.parser.ELParser.CompositeExpression(ELParser.java:40)
    at org.apache.el.lang.ExpressionBuilder.createNodeInternal(ExpressionBuilder.java:93)
    ... 64 more

1
这个问题不是JSF 2特定的,而是JSP-EL 2.2特定的。 - BalusC
4个回答

25

如其他答案中所述,您需要将el-api-2.2.jar添加到Tomcat服务器的lib文件夹中,并将el-impl-2.2.jar添加到WEB-INF / lib文件夹中。

其他答案提到删除jasper或创建ExpressionFactoryImpl的自定义实现。那可能有效,但您不应该需要这样做。

您只需要使用MyFaces上的org.apache.myfaces.EXPRESSION_FACTORY或Mojarra上的com.sun.faces.expressionFactory覆盖表达式工厂实现即可。

<context-param>
    <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
  <context-param>
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
  </context-param>

谢谢。我在网上尝试了两天所有的解决方案,而这是唯一有效的一个。 - ali
建议将 -api jar 放在服务器端路径上似乎不是常识。-api 通常意味着这是一个规范,只需要在编译时使用(可以在 Maven 中使用“provided”范围来完成)。此外,如果您提供自己的实现,我建议将其放在 Maven 项目中,并使用“runtime”范围。我故意将可能与服务器端库冲突的问题留给大家自行解决... 如果 Tomcat 分发中已经提供了实现,那么我们在这里就会有冲突。 - YoYo
1
Tomcat已经在其路径中拥有一个el-api,但它是一个非常旧的版本,他想使用一个更新的版本。当然,在2015年这个时候,升级Tomcat会更有意义,但当最初提出这个问题并且在切换到其他东西(例如Glassfish,它对他有效)不是一个选项的情况下,替换过时的el-api是唯一的真正选择。 - Lawrence McAlpin

8

正如我在评论中提到的,这可以通过升级EL实现(即用el-impl-2.2.jar替换jasper-el.jar)来解决。


2

您可以使用JBoss EL。

这是Expression Language 2.1的实现。但它有扩展,允许像您的示例一样使用方法参数:

<h:commandButton action="#{myBean.myAction(myParameter)}"/>

优点在于您只需要更改您的webapp,而不是Tomcat的lib目录。
指令:
  1. Download the latest version of Seam 2
  2. Extract lib/jboss-el.jar
  3. Copy it to WEB-INF/lib/jboss-el.jar
  4. In your web.xml set:

    <context-param>
        <param-name>com.sun.faces.expressionFactory</param-name>
        <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
    </context-param>
    

另请参阅在EL中调用直接方法或带参数的方法


1

将el-api.jar和el-impl.jar替换为el-api-2.2.jar和el-impl-2.2.jar可以解决问题。

此外,您需要在context.xml中添加上下文参数。

<context-param>
    <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
  <context-param>
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
  </context-param>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接