JSP EL 表达式 ${message} 不解析,原样输出问题

原创 jspel

在写 Spring MVC 教程的过程中,使用 IDEA 创建 Maven 工程,结果 JSP 页面上的 EL 表达式不能正常解析,原样给输出了。

<p>Hello, ${message}</p>

直接在页面上显示 Hello, ${message},其实后台 Controller 是给了一个字符串值的。

瞅了半天,原来 IDEA maven archtype:generate 创建的 web 工程默认情况下,web.xml 里面 schema 定义使用了 servlet 2.3,导致不能正常解析 JSP EL 表达式。

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
</web-app>

详细分析

根据 Oracle 文档 https://docs.oracle.com/cd/E19316-01/819-3669/bnaic/index.html 描述:

If isELIgnored is true, EL expressions are ignored when they appear in static text or tag attributes. If it is false, EL expressions are evaluated by the container only if the attribute has rtexprvalue set to true or the expression is a deferred expression.

The default value of isELIgnored varies depending on the version of the web application deployment descriptor. The default mode for JSP pages delivered with a Servlet 2.4 descriptor is to evaluate EL expressions; this automatically provides the default that most applications want. The default mode for JSP pages delivered using a descriptor from Servlet 2.3 or before is to ignore EL expressions; this provides backward compatibility.

如果 isELIgnoredtrue,当 EL 表达式出现在文本或者标签属性时被忽略。如果是 false,则 EL 表达式通过容器来决定如何解析,只有属性有返回表达式被设置为 true 或者表达式是一个延迟表达式时不解析。

isELIgnored 的值取决于 web 应用部署描述符的版本。

使用 Servlet2.4 的描述符的 JSP 页面默认是解析 EL 表达式的,即表达式有效。这默认提供了大部分应用想要的情况。

而使用 Servlet2.3 或者更早的描述符的 JSP 页面默认是忽略 EL 表达式的,即不解析 EL 表达式,这样就提供了向后兼容性。

也就是说,描述符 2.4 或者更新的版本,isELIgnored 默认值为 false,而 2.3 或者更早的版本 isELIgnored 默认值为 true。就导致了出现 EL 表达式无效的情况。

解决方法分两类。

继续使用 Servlet 2.3

如果必须继续使用 Servlet 2.3,那么有两中办法解决 EL 表达式不解析的问题。

方法一

根据上面提到的 Oracle 文档,在 JSP 页面开头添加标签,启用 EL 表达式解析。

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page isELIgnored="false" %>

方法二

网上还有一个解决方案,我没有测试,原理也是设置 jsp 的 el 表达式是否可用,应该可以使用。

在 web.xml 文件中添加如下配置:

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <el-ignored>false</el-ignored>
        <scripting-invalid>true</scripting-invalid>
    </jsp-property-group>
</jsp-config>

改用更新版本的 Servlet

如果不是必须使用 Servlet 2.3,可以使用更新版本的 Servlet 来避免这个问题,比如我创建的例子工程其实使用的是 Servlet 3.1,那么就可以把 web.xml 的 schema 头改掉,一劳永逸。

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
</web-app>
如果觉得这对你有用,请随意赞赏,给与作者支持
评论 0
最新评论