Idea的springMVC项目,jsp页面的EL表达式失效问题,数据显示不出来。(已解决)


一、问题


在做一个demo,因为很久没有重新用 jsp 页面直接 EL 取数据了,遇到了问题,记录一下。

简单来说就是用 EL 在 jsp 页面里面从域中用 ${ xxx } 取数据:

  • 但是浏览器对应页面的位置是空白
  • 也没有显示 ${ xxx } 这个表达式的字符串本身

二、前置条件:


  1. 已经引入了 jstltaglibs 的依赖;
  2. 引入依赖之后在 jsp 页面的头部需要添加命名空间,也就是 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 这样的声明,否则在 IDEA 里面写 EL 表达式时没有提示的,也会报错;
  3. EL 表达式语法正确,idea的提示里面可以直接写一个域里的属性名称,比如我的例子 requestScope.xxx,用点操作符反倒没有后面的提示,而直接写 xxx 会有提示。

因为这些都没有问题,所以我先排查了一下会不会是数据本身:

  1. 重新发请求看了一下网络状态:没有问题;
  2. 检查 jsp 的网页代码,html 的 body 都是空白,于是重新写了点数据,再次显示发现,除了 El 表达式的部分,其他都是可以正常显示的。

三、解决


查了很多资料,jstl 的依赖、servlet版本匹配等等。(未解决)

3.1 版本匹配:没问题


3.2 是否添加 jstl 依赖:正常无错误,并且引入了命名空间,结果就是在编写 EL 的时候本身并不会报错。


3.3 web.xml 中有个元素的约束版本(解决)


后来又看到一个博主提到web.xml 中有个元素的约束版本。

因为在idea 里面用原型模式构建一个 maven : web-app 项目,然后添加 springmvc 的依赖,这是构建的过程,但是点开 web.xml 之后可以看到根元素,这个 web-app 元素里面没有任何东西,反倒是前面多了一个 !DOCTYPE 元素。

web.xml头部指定的模式(Schema)文件中定义了多少种标签元素,web.xml中就可以出现它的模式文件所定义的标签元素,它就能拥有定义出来的那些功能。

事实上,web.xml的模式文件是由Sun公司定义的,每个 web.xml 文件的根元素中,都必须标明这个 web.xml 使用的是哪个模式文件。

有四个属性:

  • xmlns:申明了web.xml文件的名称空间的xml方案文档的位置;
  • xmls:xsi:指定了命名空间的案例;
  • xsi:schemeLocation:指定了发方案的位置;
  • version:制定方案的版本;

诶?那我们重新看一眼格式确实有点问题,其实和对应 servlet 的版本有关,用 idea 自动生成的时候,根元素里面表面它使用的是 2.3 版本的文件,实际上模式文件和对应的 java 版本更新早就已经到了4.0版本了,不同版本之间的特性也有差异,并且从对应 servlet 2.3 往后的约束文件,都已经不再是 dtd 而是 xsd 文件格式了。

那么对于使用 2.3 servlet 版本的这个dtd文件的约束,里面是有一个默认的属性 isELIgnored,如果 isELIgnored 是 true,当 EL 表达式出现在文本或者标签属性时被忽略。

  • 使用Servlet2.4的描述符的JSP页面默认是解析EL表达式,即表达式有效。这默认提供了大部分应用想要的情况。
  • 而使用 Servlet2.3 或者更早的描述符的 JSP 页面默认是忽略EL表达式的,即不解析EL表达式,这样就提供了向后兼容性。

因此对于我的问题,显然就是整个指定的可以这样:

  1. 在每一个 jsp 文件的头部都添加:
<%@page isELIgnored="false" %>

将保证 EL 表达式的有效。修改之后成功

  1. 修改web.xml。只要修改成对应版本为 2.4 以后的就可以了,那么看到 javaEE 版本和servlet、以及 tomcat 的对应关系,还可以直接改成 servlet4 以后的就可以了。(这个写法我认为官网应该有个统一示例,但是没找到)参考了一个人的总结,比如3.1如下:
<web-app 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"
         version="3.1">
</web-app>

这样,最前面的那个 !DOCTYPE 就可以删掉,修改之后成功

  1. 后来我又想,我在 pom.xml 创建 servlet 依赖的时候,指定的 servlet 版本是很高的,那么对应的 EL 表达式应该是有效的。如果这里不声明,那么 web.xml 解析的时候会不会自己去找对应的版本?试了一下,直接把前面 !DOCTYPE 删掉,后面的 元素也保持空的。事实上也可以成功
posted @ 2020-10-13 21:24  Life_Goes_On  阅读(1277)  评论(0编辑  收藏  举报