我有一个自定义的jsp标签,用于输出弹簧形式输入字段(以及其他布局元素)。我需要做的是能够接受动态属性并按原样在输入字段中使用它们。
例如使用:
<mytag:myinputtag arbitraryAttribute="value"/>
应输出
<input:form arbitraryAttribute="value" />
不幸的是,它没有按预期工作,因为它会抛出一个未终止的形式:输入标记异常。 以下是我使用的代码:
<%@ tag dynamic-attributes="attributes" %>
<c:set var="expandedAttributes">
<c:forEach var="a" items="${ attributes }">
${a.key}="${a.value}"<%= " " %>
</c:forEach>
</c:set>
<form:input (...) ${expandedAttributes} />
我可以理解为什么由于EL expr和标签的分辨率顺序,它没有按预期工作。因此我还测试了使用scriptlet直接注入
<form:input (...) <%= (String)jspContext.getAttribute("expandedAttributes")%> --%>
所以我需要一个解决这个问题的方法,因为我无法预览可以添加到输入的所有属性。因此我想到了以下几种可能性:
<input
代替<form:input
,这意味着我必须完全复制&#34;路径&#34;的弹簧代码。属性(不是好主意)我想知道是否有一个更好的解决方案我还没有,或者第二种可能性是否可行。
由于
答案 0 :(得分:1)
在这个问题上工作了一个月之后我已经考虑过删除和删除标记文件alltogheter 。
没有任何实现允许我按照我的意愿注入属性,所以我改变了方法并尝试生成一个标记,生成一个主体,然后对其进行评估。此方法也不起作用,因为jsp和标记在执行之前编译,因此无法在标记体中注入JSP代码。
所以我找到了一个目前有效的解决方案,它是这样的:
我创建了自己的输入标记,该标记从spring InputTag.java
扩展而来。
此标记接受名为dynAttrs
的特殊属性java.util.Map
;这些是从我的父标记传递的动态属性。其余的有效/接受标记属性与spring输入标记相同。
然后在writeTagContent
方法中,我检查dynAttrs
是否可用,以及我所做的每个属性:
PropertyAccessor
设置值(例如onClick
)data-customData
)从这里开始,我只需要调用super.writeTagContent()和voilà,spring对我来说真的很神奇!
使用示例:
<my:customTextField path="model.path" attr1="val1" attr2="val2" disabled="true"/>
它将在
中转换<div class="bla bla bla">
<my:input path="model.path" disabled="true" dynAttrs="[{attr1,val1},{attr2,val2}]"/>
</div>
并在
中转换为流<div class="bla bla bla">
<form:input path="model.path" disabled="disabled" attr1="val1" attr2="val2"/>
</div>
然后将呈现为
<div class="bla bla bla">
<input id="model.path" name="model.path" disabled="disabled" attr1="val1" attr2="val2"/>
</div>
所以我可以在运行时动态地在spring的输入标签中注入任意数量的动态属性!
注意:由于我不喜欢这种方法,但我已经为此解决方案准备了两个其他实现:
使用apache common的 BeanUtils.populate 直接用dynAttrs填充标记,但在这种情况下错误管理可能很关键。
在 hashmap 中缓存此标记中的所有可访问字段,并使用field.setValue(this,dynAttrs.get(attrName))
手动更新它们(应该更快,因为它不需要每个都检索字段打电话,但也许PropertyAccessor
做同样的事情?)。