通过属性和正文指定 JSTL <c:set> 值的区别

Posted

技术标签:

【中文标题】通过属性和正文指定 JSTL <c:set> 值的区别【英文标题】:Difference between specifying JSTL <c:set> value via attribute and body 【发布时间】:2015-12-22 21:16:29 【问题描述】:

我试图弄清楚 JSTL &lt;c:set&gt; 标记的这两种用法之间是否存在任何功能差异。假设我通过以下方式将一些字符串常量导入到我的 JSP 页面中:

<%@ page import="some.package.of.AppConstants"%>

那么,给定上面的导入指令,这两个例子有什么区别:

    value属性中指定值:

    <c:set var="SOME_VAR" value="$AppConstants.SOME_CONSTANT" />
    

    在标签正文中指定值:

    <c:set var="SOME_VAR">
        <%=AppConstants.SOME_CONSTANT%>
    </c:set>
    

第二个示例与第一个示例中$SOME_VAR 的值有什么不同吗?在这两种情况下,AppConstants.SOME_CONSTANT 中是否存在任何特殊字符会影响$SOME_VAR 的值?

【问题讨论】:

【参考方案1】:

jstl c:set value in attribute和tag body的区别

存在技术差异。

value 保留原始值类型。例如,如果您提供了 Integer 或其他内容,它将保持为 Integer。然而,主体基本上对值执行toString(),因此基本上将任何类型转换为String。这在某些情况下可能是有益的,例如:

Convert integer value to string using JSTL/EL How to find length of an integer in JSP? How to check isNumeric/IsNumber in JSTL how to get the base url from jsp request object?

回到具体的功能要求,第一个示例仅适用于您使用 web.xml 与 Servlet 3.1 匹配的 webapp 的 Servlet 3.1 / EL 3.0 容器(Tomcat 8 等)。

<c:set var="SOME_VAR" value="$AppConstants.SOME_CONSTANT" />

也就是说,这仅从 EL 3.0 开始支持。这绝对是 Scriptlet 方式的首选方法。您应该不惜一切代价尽量避免使用 Scriptlets。您只需要记住,代码不向后兼容旧版本的目标运行时。

另见:

How to reference constants in EL? How to avoid Java code in JSP files?

【讨论】:

【参考方案2】:

根据 O'Reillys HeadsFirstServlets pg 457,为什么要使用 c:set 的主体版本而不是无主体版本。看起来他们做同样的事情。

答案:

那是因为他们确实... 一样。正文版仅适用于 当您想要更多空间时方便 价值。这可能是一个漫长而复杂的 表达式,例如,并将其放入 正文更易于阅读。

更新

经过一些额外的研究,结果证明上述推理仅适用于 EL v2.2 及更低版本。请参阅 BalusC 对 3.0 行为的回答。

【讨论】:

感谢您的评论。事实证明,我的问题与使用属性与主体来分配值无关。我终于发现关键区别在于我分配值的方式,在第一个示例中使用表达式,在第二个示例中使用 scriptlet。事实证明,在 Expression Language 2.x 中,导入的类/接口不在范围内,因此无法使用 EL 引用(例如:$AppConstants.SOME_CONSTANT)。相反,它们必须通过 scriptlet 来引用。无论如何我都会投票赞成你的回复,因为你是唯一一个试图建设性地回答的人

以上是关于通过属性和正文指定 JSTL <c:set> 值的区别的主要内容,如果未能解决你的问题,请参考以下文章

JSTL之c:set

jsp:jstl标签forTokens

JSTL c:set 和 Struts s:set 是不受欢迎的数字格式

JSTL--JSTL表达式:c:set,c:if,c:choose,--drp214

JSTL核心标签库

jstl标签