题
我正在考虑创建一些始终提供相同输出的 JSP 标签。例如:
<foo:bar>baz</foo:bar>
总是会输出:
<div class="bar">baz</div>
有没有办法让 JSP 标签的行为就像生成的 servlet 中的静态输出一样?
例如:
out.write("<div class=\"bar\">");
...
out.write("</div>");
代替
x.y.z.foo.BarTag _jspx_th_foo_bar_0 = new x.y.z.foo.BarTag();
_jspx_th_foo_bar_0.setPageContext(pageContext);
_jspx_th_foo_bar_0.setParent(null);
_jspxTagObjects.push(_jspx_th_foo_bar_0);
int _jspx_eval_foo_bar_0 = _jspx_th_foo_bar_0.doStartTag();
etc...
etc...
etc...
背景
我担心表现。我还没有对此进行测试,但看起来生成的 servlet 对于一些非常简单的事情做了很多工作,并且性能非常重要。
但是,如果 servlet 的行为就像输出直接写入 JSP 中一样,那么生产成本将为零。
我看到这样做有一些好处。我可以更改静态 HTML,甚至更改为更动态的内容,而无需编辑每个 portlet。在我们的设置中,更改标签很容易,但更改使用特定元素的每个 JSP 却非常耗时。
这也意味着我可以强迫开发人员不要写类似的东西
<div class="bar" style="whatever">...</div>
还有更多优势,但如果它会影响生产服务器的性能,则可能不值得。
解决方案 2
我做了一个性能测试。性能差异很小,所以没有问题。
我是如何进行测试的
我在我们的标签库之一中(以编程方式)创建了 500 个单独的标签。(因此它被包裹在罐子等中。)它们看起来像这样,数字是唯一的区别:
package XX.XX.XX.XX
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class Test0001Tag extends TagSupport {
public Test0001Tag() {
}
public int doStartTag() throws JspException {
try {
pageContext.getOut().print("<div class=\"Test0001\">");
} catch (IOException e) {
throw new JspException(e);
}
return EVAL_BODY_INCLUDE;
}
public int doEndTag() throws JspException {
try {
pageContext.getOut().print("</div>");
} catch (IOException e) {
throw new JspException(e);
}
return EVAL_PAGE;
}
public void release() {
super.release();
}
}
然后 TLD 中有 500 个条目,如下所示:
<tag>
<name>test0001</name>
<tagclass>XX.XX.XX.XX.Test0001Tag</tagclass>
<bodycontent>JSP</bodycontent>
</tag>
然后我抓起一个包含一些代码的 JSP,并复制了两份:一种是静态 HTML,另一种是标签。
静态 HTML 的一种:
<!--
<%long start = System.currentTimeMillis();%>
<% for (int i = 0; i < 1000; i++) { %>
<div class="Test0001">X</div>
<div class="Test0002">X</div>
<div class="Test0003">X</div>
...
<div class="Test0498">X</div>
<div class="Test0499">X</div>
<div class="Test0500">X</div>
<% } %>
<%System.out.println(System.currentTimeMillis()-start);%>
-->
带有标签的:
<!--
<%long start = System.currentTimeMillis();%>
<% for (int i = 0; i < 1000; i++) { %>
<bddesign:test0001>X</bddesign:test0001>
<bddesign:test0002>X</bddesign:test0002>
<bddesign:test0003>X</bddesign:test0003>
...
<bddesign:test0498>X</bddesign:test0498>
<bddesign:test0499>X</bddesign:test0499>
<bddesign:test0500>X</bddesign:test0500>
<% } %>
<%System.out.println(System.currentTimeMillis()-start);%>
-->
引入循环是因为两者的结果都是零毫秒。(不幸的是,我在工作中运行Windows,所以我在这里没有太多的精确度。)500标签无法实现可衡量的延迟的事实可能已经足够回答了,但是即使重复允许的重复也是如此一些优化。
500 000 个标签的结果:
- JSP 标签:15-19秒
- HTML 标签:12-16秒
所以这是有区别的,但我认为与从用户点击到答案呈现在屏幕上所发生的所有其他事情相比,这是微不足道的。
其他想法
据我所知,Windows 中的粒度约为 15-16 毫秒。所以“0毫秒”实际上意味着“<16毫秒”。平均延迟小于 16/500 毫秒。标签是完全可以接受的。
我尝试使用 1000 个标签,但 JSP 编译器对此非常不满意。我减少到 500 个标签,因为替代方法是更改设置,这会使我的结果无效。
我将生成的 HTML 设为 HTML 注释,因为浏览器与测试服务器位于同一台物理机上,而且我担心浏览器会占用太多 CPU 时间渲染,即使使用双核 CPU 也是如此。最简单的解决方案是对 HTML 进行注释。
其他提示
考虑到您刚刚展示的代码,我确信性能损失是可以忽略不计的。
我在想......为什么不使用普通的包含?