JSTL与JSP Scriptlets

时间:2010-12-26 21:08:00

标签: java jsp jstl

我希望有人在this question中解释BlausC的惊人答案中的一些要点。

他说小脚本有一些缺点,包括:

  1. 可重用性:您无法重用scriptlet。我的问题:如何重用JSTL代码?

  2. 可替换性:您不能将scriptlet抽象化。抽象是什么意思,JST如何变得抽象?

  3. OO:你不能使用继承/组合。我如何在JSTL中使用OO范例?

  4. 调试:如果一个scriptlet中途抛出异常,你得到的只是一个空白页。

  5. 可测试性:无法对scriptlet进行单元测试。这是什么意思,JSTL如何进行单元测试?

  6. 可维护性:每个saldo,需要更多时间来维护混杂/混乱/重复的代码逻辑。这是什么意思?

  7. 最后一件事是他引用甲骨文的建议:

      

    JSP scriptlet不应该用于编写业务逻辑。

    在MVC模式中,我只在表示层使用scriptlet。他的意思是什么?

6 个答案:

答案 0 :(得分:16)

您似乎只关注scriptlet的表示和流控制部分,就像使用ifforswitch语句以及out.print()一样。您似乎将Scriptlet 1:1与JSTL进行比较。这是错的。我不是只谈论流控制部分(实际上是由JSTL取代),而是关于在JSP文件中编写原始Java代码。即收集请求参数,验证和转换值,与数据库和其他Java类/方法交互等等。您通常(间接)在Servlet或Filter中执行的所有操作。

答案 1 :(得分:14)

你应该在JSP中拥有scriptlet代码。我推荐100%JSTL和零写代码。

JSP应该是纯粹的表示。这是使用JSTL编写JSP的隐藏好处,因为它们可以在其他地方获取所有动态数据。让服务层具有业务逻辑并确定JSP需要哪些数据。

这也回答了你的单元测试问题。您不应该单元测试JSP;那些将是类似Selenium的UI测试。如果逻辑在服务层中,那么你很明显如何测试它。

不应继承JSP。你当然可以使用类似SiteMesh的东西将它们组合在一起,但是继承在你的JSP中没有任何作用。一旦他们从Servlet继承,链就应该结束了。

此外,这是一个错误的选择。两者都不应该要求重用,继承或单元测试。但这并不意味着没有一个明显的赢家:它是JSTL。没有人应该在JSP中使用scriptlet,除了非常罕见的单行程序。 Scriptlets正在乞求麻烦。

现在我更喜欢Velocity作为Java的Web UI模板解决方案,而不仅仅是JSP。只是我的意见。

答案 2 :(得分:4)

我不能代表BalusC发言,但总的来说我相信他认为这些事情应该由你的普通Java代码完成(如果你进入整个MVC的话,在Controller和Model层中) )。

  1. 您无法在单个级别上重复使用JSP标记,但您可以重用它们调用的类。

  2. JSTL不能是抽象的,但普通的Java代码(你可以从JSTL调用)可以是。

  3. 同样,你不能在jstl中有用地创建对象,但你可以在所有被调用的类中使用。

  4. JSTL本身不是单元可测试的。但是你通过它调用的类和方法是。

答案 3 :(得分:1)

这取决于您使用的模式。通过使用 MVC spring,struts,... ),您应该避免在JSP中使用scriptlet,因为它代表了应该包含纯XHTML标记的视图。 JSTL是一种声明性语言,某种XML,而scriplet则不是。

特别是我通过prototype使用 JSTL与AJAX 组合来生成RIA而无需实现其他模式。最近我看到了ExtJSDWR的这种编程。在我的情况下,我发现有必要将JSTL和scriplet结合起来,在可能的情况下总是更喜欢JSTL。

<!-- simple controller, each action is called by means of AJAX -->
<% String signExt="jpg"; %>
<% int r=0, iMaxRows=0, iMaxCols=0;%>
<c:choose>

    <c:when test="${param.action == 'get_chrequest_profile_table_by_family_and_date'}">
        <sql:query var="dataset">
            CALL GetProfilesView('<c:out value="${param.family_name}" />', '<c:out value="${param.reg_date}" />')
        </sql:query>

        <c:set var="strElements"><c:out value="${dataset.rowCount}" /></c:set> 
        <%  
        String strElements = pageContext.getAttribute("strElements").toString();
        int iElements = (int)Integer.valueOf(strElements).intValue(); 
        String to = "";
        %>

        <table class="tb_profiles" id="tb_profiles" iElements="<%=iElements%>"
               width="100%" frame=void border="0" cellPadding="0" cellSpacing="0" style="border-top: 3px solid gray; border-left: 1px solid gray">

            <%for(int i=1, j=0, col=0; i<100; i++){%>
            <tr>
                <%for(j=0; j<4; j++, col++){%>
                <c:set var="c" scope="page"><%=col%></c:set>

                <td name='<c:out value="${dataset.rows[c].chreqprofile_id}" />' >
                    <table width="100%" frame="below" cellPadding="0" cellSpacing="0"style="border-right: 1px solid gray;">

                        <%if( col < iElements){%>
                            <tr style="height:10mm">
                                <td class="td_function" style="cursor:default;">
                                    <c:out value="${dataset.rows[c].description}" />
                                </td>
                            </tr>
                            .................
                            <tr style="height:14mm">                        
                                <td class="td_signature" align="center" vAlign="middle">
                                    <img class="img_signature"
                                         src='../xdata/signatures/<c:out value="${dataset.rows[c].responsible_name}"/>.<%=signExt%>'
                                         alt='<c:out value="${dataset.rows[c].email}" />' 
                                    />
                                </td>
                            </tr>
                            .................

                            <c:set var="sMail"><c:out value="${dataset.rows[c].email}"/></c:set>
                            <% if( col < iElements-1){
                                    to = to + pageContext.getAttribute("sMail").toString() + ","; 
                               }else{
                                    to = to + pageContext.getAttribute("sMail").toString();
                               }
                            %>                      
                        <%}else{%>
                            <tr style="height:10mm">
                                <td class="td_function" style="cursor:default;">x</td>
                                .............
                            </tr>
                        <%}%>
                    </table>
                </td>               

                <%}%>
            </tr>
            <%
                if( col >= iElements){break;}
            }%>
        </table>
        <span id="span_mail_to" style="display:none;"><%=to%></span>        
    </c:when>   
    <c:when test="${param.action == 'functions_form_insert'}">  
        .............
    </c:when>   
</c:choose>

答案 4 :(得分:1)

我没有看到scriplets特别糟糕,如果你遵循它的设计模式,我在spring mvc上工作很多,在我的jsp中我只是在scriplits中获取模型数据,并且我使用简单的java向用户显示它在HTML中的代码,我觉得它给了我比JSTL更多的自由。

答案 5 :(得分:0)

这是一个比较JSP和Facelets的表,它可能对某人有帮助:

Source