JSTL与JSP Scriptlets
我想在这个问题上有人解释一下BlausC的惊人答案。
他说,脚本有一些缺点,它们是:
-
可重用性:您不能重用脚本。 我的问题是:我如何重用JSTL代码?
-
可replace性:您不能使脚本抽象化。 抽象是什么意思,JST如何变得抽象?
-
OO:你不能使用inheritance/组合。 我怎样才能在JSTL中使用面向对象的范例?
-
debugging:如果一个scriptlet中途抛出一个exception,你得到的只是一个空白页面。
-
可testing性:脚本不能被unit testing。 这意味着什么,JSTL如何进行unit testing?
-
可维护性:每个saldo需要更多的时间来维护混合/混乱/重复的代码逻辑。 这是什么意思?
最后一件事是他引用Oracle的build议:
JSP脚本不应该用于编写业务逻辑。
在MVC模式中,我仅在表示层中使用scriptlet。 他在这里是什么意思?
您似乎只专注于使用if
, for
和switch
语句和out.print()
事件的scriptlet的表示和stream控制部分。 你似乎比较了JSTL的1:1脚本。 这是错误的。 我并不是只谈论stream程控制部分(这实际上是由JSTL取代),而是一般在JSP文件中编写原始Java代码。 即收集请求参数,validation和转换值,与数据库和其他Java类/方法交互等等。通常(间接)在Servlet或Filter中执行所有的事情。
JSP中不应该有scriptlet代码。 我推荐100%JSTL和零脚本代码。
JSP应该是纯粹的演示。 这是仅使用JSTL编写JSP的隐藏好处,因为它们将其所有dynamic数据都存储在别处。 让服务层拥有业务逻辑并确定JSP需要什么数据。
这也回答你的unit testing问题。 您不应该对unit testingJSP; 那些将是像selenium的UItesting。 如果逻辑在服务层中,那么testing它就显而易见了。
JSP不应该被inheritance。 你当然可以用SiteMesh来组合它们,但是inheritance在你的JSP中没有任何部分。 一旦从Servletinheritance,链应该结束。
此外,这是一个错误的select。 都不应该要求重用,inheritance或unit testing。 但这并不意味着没有一个明确的赢家:这是JSTL。 没有人应该在JSP中使用scriptlet,除非是非常罕见的单行程序。 Scriptlets正在乞求麻烦。
现在我更喜欢Velocity作为我的Java的Web UI模板解决scheme,远远超过了JSP。 只是我的观点。
我不能说BalusC,但总的来说,我相信他已经意识到这些东西应该由普通的Java代码来实现(如果你是整个MVC的话,在Controller和Model层中)。
-
您不能在个人层面重新使用JSP标签,但可以重用他们所调用的类。
-
JSTL不能是抽象的,但是普通的Java代码(你可以从JSTL中调用)是可以的。
-
同样,你不能在jstl中有用地创build对象,但是你可以在所有被调用的类中使用。
-
JSTL本身不是unit testing的。 但是你通过它调用的类和方法是。
这取决于你使用的模式。 通过使用MVC ( spring,struts,… ),您应该避免在JSP中使用scriptlet,因为它代表了它应该包含纯XHTML标记的视图。 JSTL是一种声明性语言,某种types的XML,而scriplet则不是。
特别是我已经使用JSTL与AJAX通过原型生成RIA,而不需要实现另一种模式。 最近我用ExtJS和DWR看过这种编程。 在我的情况下,我发现有必要结合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>
我没有看到,特别是如果你遵循其中的devise模式,我工作了很多,我的jsp工作了很多,我的jsp我只是在scriplits模型数据,我显示它给用户在HTML中使用简单的Java代码,我觉得这比JSTL给了我更多的自由。
下面是一个比较JSP和Facelets的表格,这些表格可能对某个人有帮助:
资源