代码之家  ›  专栏  ›  技术社区  ›  myplacedk

带有静态输出的JSP标记

  •  1
  • myplacedk  · 技术社区  · 17 年前

    我正在考虑创建一些总是提供相同输出的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>
    

    还有更多的优势,但是如果它在生产服务器上牺牲性能,那么它可能不值得。

    3 回复  |  直到 17 年前
        1
  •  3
  •   Jonas K    17 年前

    考虑到您刚刚显示的代码,我很确定性能命中率会很低。

        2
  •  1
  •   myplacedk    17 年前

    我做了一个性能测试。表演上几乎没有差别,所以没问题。

    我是怎么做测试的

    我在我们的一个标签库中创建了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个标签没有使一个可测量的延迟可以得到足够的答案,但我想要更多,即使重复可以允许一些优化。

    500000个标签的结果:

    • JSP标签:15-19秒
    • HTML标记:12-16秒

    所以有一个区别,但是我认为与其他一切相比,从用户点击到答案都在屏幕上呈现,这是微不足道的。

    其他想法

    据我所知,Windows中的粒度大约为15-16毫秒。所以“0毫秒”实际上意味着“16毫秒”。延迟小于16/500毫秒是可以接受的。

    我尝试使用1000个标记,但是JSP编译器对此非常不满意。我减少到500个标签,因为另一个选择是更改设置,这将使我的结果无效。

    我将生成的HTML作为HTML注释,因为浏览器与测试服务器在同一台物理机器上,而且我担心浏览器会花费太多的CPU时间呈现,即使使用双核CPU。简单的解决方案是对HTML进行注释。

        3
  •  0
  •   abahgat    17 年前

    我在想…为什么不只用一个普通的老 包括 ?