为什么在JSP中通过EL表达式无法显示Model中的数据

HTTPS

在Spring MVC的开发过程中,我们将一个值存放到Model中然后在JSP页面中通过EL表达式显示出来,就像这样${name}
但是当运行起来通过浏览器查看效果时,它竟然原样输出了${name},EL表达式似乎根本就没有工作。

那么问题来了

先看看代码有没有问题:

Spring’s Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class ChatController {
@RequestMapping("/foo")
public String foo(String name, Model model){
model.addAttribute("name", name);
return "hello";
}
}

hello.jsp

1
2
3
4
5
6
7
8
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
</head>
<body>
<h1>Hello ${name} !</h1>
</body>
</html>

代码没有什么问题,这感觉就一个字:这不科学!

解决办法

1、在JSP中通过JSP指令关掉EL忽略解析

1
2
3
4
5
6
7
8
9
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page isELIgnored="false" %>
<html>
<head>
</head>
<body>
<h1>Hello ${name} !</h1>
</body>
</html>

打开浏览器看看,嗯,解析并得到了想要的结果,但你肯定会纳闷了,以前开发过程中也没去设置也照样好好的啊?那接着往下看

2、在web.xml中关闭EL忽略解析

1
2
3
4
5
6
7
8
9
10
11
12
<!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>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>false</el-ignored>
</jsp-property-group>
</jsp-config>
</web-app>

当然,跟前一种方式对比,也就是全局控制和局部控制的差别,可以解决问题,但是到底是什么原因呢?

3、web.xml文档声明惹的祸

这是大多数 SpringMVC 实践过程中通常会遇到的问题,事实上它是由于web.xml采用了旧的文档声明(Servlet 2.3 / JSP 1.2)导致的
此时EL表达式忽略不解析默认为开启),如下,在你的web.xml文件可能是这个样子,

1
2
3
4
5
6
7
<!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>

你可以打开 DTD 对应链接,下载后打开查看37行的位置

1
2
3
4
5
6
7
8
9
10
<!--
This is the XML DTD for the Servlet 2.3 deployment descriptor.
All Servlet 2.3 deployment descriptors must include a DOCTYPE
of the following form:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
-->

那么现在,采用 Servlet 2.3 以上的文档声明,就可以不用再多写别的配置(方法1或方法2)了,比如一个2.4的应该像这样:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/javaee http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd"
version="2.4">
...
</web-app>

EL表达式是不是乖乖的工作了?好了,继续早该完成的工作吧。