如果您完全重新设计您的 JSP 文件(如果我自己这么说的话,这是一种非常丑陋的方式),可能会为您的视图添加类型安全性。
Servlet 为您提供类型安全,因为那是 Java 代码。如果你重构你的类并且遗漏了一些东西,编译器会立即告诉你你错过了它。但是 JSP 将 servlet 替换为一种视图技术,提供了更加动态/快速的开发速度(不再有无休止的out.write
打开标签、关闭标签、转义引号等指令)。
正如您所注意到的,EL 表达式基本上是字符串,如果出现问题,稍后会对其进行评估并在运行时失败。即使您预编译 JSP,它仍然会失败,因为 EL 在生成的 servlet 中仍然是字符串。它们要么按原样传递给标记并自行评估,要么如果使用 JSP 2.x 版本,则 servlet 容器本身将表达式包装在评估调用中,然后将其作为值传递。
基本上对于低于 JSP 2 的版本,对于像这样的标签:
<my:tag value="${bean.someProp}" />
你会得到如下结果:
myTagInstance.setValue("${bean.someProp}");
在 servlet 中。
标签本身将在运行时对该字符串进行评估。
对于 JSP 2,您并没有变得更好,评估仍然发生在运行时,但 servlet 容器从标记中消除了这个负担,生成如下代码:
myTagInstance.setValue((SomePropTypeCastHere) ProprietaryServletContainerEvaluationUtil.evaluate("${bean.someProp}"));
如果在评估发生时对象本身的内容不是预期的内容,您会得到奇怪的结果或错误。
在 JSP 中强制执行静态类型的唯一方法(我知道)是将 Java 代码带回 JSP 中(发明 EL 是为了消除这种东西)。这就是为什么我在乞求时说你必须以一种丑陋的方式改变你的 JSP。
如果您的所有标签都可以使用<rtexprvalue>true</rtexprvalue>
值,那么您可以使用 scriptlet 来强制执行类型安全。
像这样的标签:
<my:tag value="<%=bean.getSomeProp()%>" />
现在转换为:
myTagInstance.setValue(bean.getSomeProp());
如果someProp
属性被重命名、删除、更改类型或其他什么,编译器可以告诉你。IDE 本身应该能够告诉您,您甚至不需要预编译 JSP。
如果我没记错的话,Spring 标签支持运行时表达式,所以这应该可以工作......如果你愿意搞乱你的 JSP,那就是!
至于 IDE 对完成的支持,您对 scriptlet 有支持,但对 EL 没有。那是因为对于 EL,它是相同的讨论,它发生在运行时。IDE 如何在执行 JSP 时知道上下文中的内容(页面、请求、会话等),以及在开发 JSP 时知道这些内容?