在Web Application开发的过程中,经常会遇到Struts,JSP,JS一起使用的情况。
在自定义Struts tag的时候,发现属性值中的JSP表达式没有被解析,原封不动的传了过来。
详情如下:
自定义了一个tag,继承org.apache.struts.taglib.html.ButtonTag. 在JSP中使用如下: <% String configUrl = "/conf/icp/deleteAction.do"; %> <icp:button id="abc" class="btn" οnclick="onDelete(event, '<%=WebUtility.escapeForJSString(configUrl)%>')" >
<fmt:message key="delete" bundle="${coreResources}"/> </icp:button> 其中onDelete是JS函数。问题是在调用onDelete函数的时候, '<%=WebUtility.escapeForJSString(configUrl)%>' 没有被解析,原封不动的传了过来。
尝试了把WebUtility.escapeForJSString(configUrl) 放在request中:
然后,用EL表达式为属性赋值:
这样,也不起作用。
后来,想了一个比较tricky的方法。
<icp:button id="buttonDelete_<%=i%>" class="btn" οnclick="onDelete(event, '<%=WebUtility.escapeForJSString(configUrl)%>')" >
<button id="buttonDelete_<%=i%>"
οnclick="onDelete(event, '<%=WebUtility.escapeForJSString(configUrl)%>')" ><fmt:message key="delete" bundle="${coreResources}"/> </button> </icp:button>
这样就把<button> tag当做文本text来处理。
public int doEndTag() throws JspException {
parseInnerButtonTag(text);
....
}
private void parseInnerButtonTag(String str) {
int begin = str.indexOf("id=");
if (begin < 0) {
return;
}
str = str.substring(begin + "id=".length() + 1);
int end = str.indexOf("\"");
String id = str.substring(0, end);
this.setStyleId(id);
this.setId(id);
begin = str.indexOf("οnclick=");
str = str.substring(begin + "οnclick=".length() + 1);
end = str.indexOf("\"");
String onclick = str.substring(0, end);
this.setOnclick(onclick);
begin = str.indexOf(">");
end = str.indexOf("</");
text = str.substring(begin + 1, end).trim();
}
这样就解决问题了。两种用法都可以。
1) 属性中没有JSP表达式
<icp:button styleId="buttonNext" οnclick="changeToDetailTab(2)" property="" styleClass="btn">
<fmt:message key="nextBtn" bundle="${coreResources}"/>
</icp:button>
2) 属性中有JSP表达式
<icp:button id="buttonDelete_<%=i%>" class="btn"
οnclick="onDelete(event, '<%=WebUtility.escapeForJSString(configUrl)%>')" >
<button id="buttonDelete_<%=i%>"
οnclick="onDelete(event, '<%=WebUtility.escapeForJSString(configUrl)%>')" >
<fmt:message key="delete" bundle="${coreResources}"/>
</button>
</icp:button>