我希望有人在this question中解释BlausC的惊人答案中的一些要点。
他说小脚本有一些缺点,包括:
可重用性:您无法重用scriptlet。我的问题:如何重用JSTL代码?
可替换性:您不能将scriptlet抽象化。抽象是什么意思,JST如何变得抽象?
OO:你不能使用继承/组合。我如何在JSTL中使用OO范例?
调试:如果一个scriptlet中途抛出异常,你得到的只是一个空白页。
可测试性:无法对scriptlet进行单元测试。这是什么意思,JSTL如何进行单元测试?
可维护性:每个saldo,需要更多时间来维护混杂/混乱/重复的代码逻辑。这是什么意思?
最后一件事是他引用甲骨文的建议:
JSP scriptlet不应该用于编写业务逻辑。
在MVC模式中,我只在表示层使用scriptlet。他的意思是什么?
答案 0 :(得分:16)
您似乎只关注scriptlet的表示和流控制部分,就像使用if
,for
和switch
语句以及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层中) )。
您无法在单个级别上重复使用JSP标记,但您可以重用它们调用的类。
JSTL不能是抽象的,但普通的Java代码(你可以从JSTL调用)可以是。
同样,你不能在jstl中有用地创建对象,但你可以在所有被调用的类中使用。
JSTL本身不是单元可测试的。但是你通过它调用的类和方法是。
答案 3 :(得分:1)
这取决于您使用的模式。通过使用 MVC ( spring,struts,... ),您应该避免在JSP中使用scriptlet,因为它代表了应该包含纯XHTML标记的视图。 JSTL是一种声明性语言,某种XML,而scriplet则不是。
特别是我通过prototype使用 JSTL与AJAX 组合来生成RIA而无需实现其他模式。最近我看到了ExtJS和DWR的这种编程。在我的情况下,我发现有必要将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的表,它可能对某人有帮助: