我最近一直在使用弹簧形式的taglib,并且遇到了一个相当令人不安的现象。
<form:select path="whatever" disabled="${true}">
将呈现未禁用的选择元素
<form:select path="whatever" disabled="${'true'}">
将呈现一个被禁用的选择元素。
这向我表明标签需要该属性中的字符串,并且拒绝强制任何布尔值(可能先检查类型)。
影响是我无法做<form:select path="whatever" disabled="${someOtherfield.selectedId != -1}" />
之类的事情,这在我们的系统中经常发生。
我是否只是遗漏了表单taglibs功能的某些部分?这是一个合法的设计决定吗?缺陷?
答案 0 :(得分:5)
好的,我在这个问题上做了一些挖掘,因为解决方案看起来太难看了。
http://forum.springsource.org/showthread.php?t=84102
问题在于JSP正在评估el,并使用“true”。盲目比较评估结果.equals
使用该方法将String与布尔值进行比较将始终返回false,因为类型不匹配所以它肯定是一个缺陷。
幸运的是,故障中的isDisabled方法是一个受保护的单行,所以我能够通过扩展8输入标记的影响并覆盖该方法来进行稍微更稳健的比较。
所以答案是,是的,这是一个缺陷,而且从skaffman的评论来看,当一个旧的库在JSP EL实现时没有很好地更新时,这看起来有点问题。
感谢您的回答
答案 1 :(得分:1)
这有点奇怪,对吧。 Spring源代码显示disabled
的{{1}}属性为SelectTag
,而不是String
。这显然不是正确的做法,但我怀疑它仍然是出于传统原因(spring-form.tld早于JSP EL)。
这使得JSP运行时将boolean
强制转换为boolean
,显然它不会这样做。我对此并不感到惊讶,因为JSP EL是众所周知的限制。
所以你陷入了两个半破坏的实现之间。您只需要确保将String值传递给该属性。
答案 2 :(得分:0)
这种设计的原因是它们有一个特殊的回退代码,当容器不对它进行评估时强制进行EL表达式评估。例如,此代码:
<%@ page isELIgnored = "true" %>
...
${'Simple text'} <spring:message text = "${'Message text'} />"
生成${'Simple text'} Message text
对于一些奇怪的传统容器配置,它可能很有用。
也就是说,如果disabled
属性为boolean
,则以下代码无效:
<%@ page isELIgnored = "true" %>
...
<form:select ... disabled = "${true}" />