Java JSTL与JSP脚本

Java JSTL与JSP脚本,java,jsp,jstl,Java,Jsp,Jstl,我想有人解释一下BlausC的惊人答案中的一些要点 他说Scriptlet有一些缺点,这些缺点是: 可重用性:不能重用Scriptlet。我的问题是:如何重用JSTL代码 可替换性:不能将Scriptlet抽象化。抽象是什么意思?JST如何变得抽象 OO:您不能使用继承/组合。如何在JSTL中使用OO范例 调试:如果一个scriptlet中途抛出一个异常,那么得到的只是一个空白页 可测试性:scriptlet不能进行单元测试。这意味着什么?JSTL如何进行单元测试 可维护性:根据saldo,需要

我想有人解释一下BlausC的惊人答案中的一些要点

他说Scriptlet有一些缺点,这些缺点是:

  • 可重用性:不能重用Scriptlet。我的问题是:如何重用JSTL代码

  • 可替换性:不能将Scriptlet抽象化。抽象是什么意思?JST如何变得抽象

  • OO:您不能使用继承/组合。如何在JSTL中使用OO范例

  • 调试:如果一个scriptlet中途抛出一个异常,那么得到的只是一个空白页

  • 可测试性:scriptlet不能进行单元测试。这意味着什么?JSTL如何进行单元测试

  • 可维护性:根据saldo,需要更多的时间来维护混合/混乱/重复的代码逻辑。这是什么意思

  • 最后一件事是他在甲骨文的建议中引用的:

    JSP脚本不应用于编写业务逻辑

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

    您不应该在JSP中使用scriptlet代码。我建议使用100%JSTL和零scriplet代码

    JSP应该是纯粹的表示。这就是只使用JSTL编写JSP的潜在好处,因为它们在别处获取所有动态数据。让服务层拥有业务逻辑并确定JSP需要哪些数据

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

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

    此外,这是一个错误的选择。两者都不需要重用、继承或单元测试。但这并不意味着没有明确的赢家:它是JSTL。除了非常罕见的一行程序外,任何人都不应该在JSP中使用Scriptlet。小脚本在自找麻烦


    现在我更喜欢Velocity作为我的Java web UI模板解决方案,而不是JSP。这只是我的观点。

    我不能代表BalusC说话,但总的来说,我相信他是在想,这些事情应该由普通Java代码来完成(如果你对整个MVC都感兴趣,那么在控制器和模型层)

  • 您不能在单个级别重用JSP标记,但可以重用它们调用的类

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

  • 同样,在jstl中不能有效地创建对象,但可以在所有调用的类中创建对象

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


  • 在使用
    if
    for
    switch
    语句和
    out.print()时,您似乎只关注scriptlet的表示和流控制部分。您似乎比较了scriptlets 1:1和JSTL。这是错误的。我所说的不仅仅是流控制部分(它确实将被JSTL取代),而是在JSP文件中编写原始Java代码。例如,收集请求参数、验证和转换值、与数据库和其他Java类/方法交互等。您通常(间接)在Servlet或筛选器中执行的所有操作。

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

    特别是我使用了JSTL和AJAXvia来生成RIA,而不需要实现另一种模式。最近我看到了与和的这种编程。在我的例子中,我发现有必要将JSTL和scriplets结合起来,只要可能,它们总是更喜欢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>
    
    
    调用GetProfilesView(“”,“”)
    
    我不认为scriplets太糟糕,特别是如果你遵循其中的设计模式,我在spring mvc上做了很多工作,在我的jsp中,我只是在scriplets中获取模型数据,然后用html中的简单java代码向用户展示,我觉得它比JSTL给了我更多的自由

    下面是一个比较JSP和Facelets的表,它们可能对某些人、某些地方有所帮助:


    我完全同意我们应该在JSP中使用JSTL,你是说服务层是控制器层吗?控制器层是视图的一部分;您还需要一个服务层,这意味着控制器集中了将请求分派到下一个视图的逻辑,因此控制器是servlet JSP开发中的servlet,而服务层是servlet中提供特定服务的部分。我说的对吗?不一定。大多数WebMVC框架都有一个前端控制器servlet,它遵从POJO控制器类。我认为servlet不应该是控制器。关键是如果你在JSP中编写一堆Java代码,你就不能扩展你在那里创建的类,重用它们,为它们编写单元测试等等。当然,如果你只是偶尔使用Scriptlet,那么可能就没有那么重要了。JSP使代码看起来很优雅,类XML、类声明性的非过程性虽然它不能使代码本身可测试、可重用,但它更好,因为Java代码不是内联的,它摆脱了Java构造和语法,这是为了增强可读性,过滤器和上下文侦听器以及JSP中的JSTL。无意冒犯,但这段代码看起来像是JSTL、Scriptlet和html的可怕混合体。@Gearoid:这段代码允许您轻松实现