[英]JSTL vs JSP Scriptlets
我希望有人在這個問題中解釋一下BlausC的驚人答案。
他說小腳本有一些缺點,它們是:
可重用性:您無法重用scriptlet。 我的問題:我怎樣才能重用JSTL代碼?
可替換性:您不能使scriptlet抽象化。 抽象是什么意思,JST如何變得抽象?
OO:你不能利用繼承/組合。 我如何在JSTL中使用OO范例?
調試:如果一個scriptlet中途拋出異常,你得到的只是一個空白頁面。
可測試性:scriptlet不能進行單元測試。 這是什么意思,JSTL如何進行單元測試?
可維護性:每個saldo,需要更多的時間來維護混雜/混亂/重復的代碼邏輯。 這是什么意思?
最后一件事是他引用甲骨文的建議:
JSP scriptlet不應該用於編寫業務邏輯。
在MVC模式中,我僅在表示層中使用scriptlet。 他在這里是什么意思?
您似乎只關注scriptlet的表示和流控制部分,就像使用if
, for
和switch
語句以及out.print()
。 您似乎將Scriptlet 1:1與JSTL進行比較。 這是錯的。 我不是只談論流控制部分(實際上是由JSTL取代),而是關於在JSP文件中編寫原始Java代碼。 即收集請求參數,驗證和轉換值,與數據庫和其他Java類/方法交互等等。您通常(間接)在Servlet或Filter中執行的所有操作。
你不應該在JSP中的scriptlet代碼。 我推薦100%JSTL和零scriplet代碼。
JSP應該是純粹的表示。 這是使用JSTL編寫JSP的隱藏好處,因為它們可以在其他地方獲取所有動態數據。 讓服務層具有業務邏輯並確定JSP需要哪些數據。
這也回答了你的單元測試問題。 您不應該單元測試JSP; 那些將是類似Selenium的UI測試。 如果邏輯位於服務層中,那么測試它的方式就很明顯了。
不應繼承JSP。 你當然可以使用類似SiteMesh的東西將它們組合在一起,但是繼承在你的JSP中沒有任何作用。 一旦他們從Servlet繼承,鏈就應該結束了。
此外,這是一個錯誤的選擇。 兩者都不應該要求重用,繼承或單元測試。 但這並不意味着沒有一個明顯的贏家:它是JSTL。 沒有人應該在JSP中使用scriptlet,除了非常罕見的單行程序。 Scriptlets正在乞求麻煩。
這些天我更喜歡Velocity作為Java的Web UI模板解決方案,而不僅僅是JSP。 只是我的觀點。
我不能代表BalusC,但總的來說,我相信他已經認識到這些事情應該由你的普通Java代碼完成(如果你進入整個MVC的話,在Controller和Model層中)。
您無法在單個級別上重復使用JSP標記,但可以重用它們調用的類。
JSTL不能是抽象的,但是普通的Java代碼(你可以從JSTL調用它)也可以。
同樣,你不能在jstl中有用地創建對象,但是你可以在所有被調用的類中。
JSTL本身不是單元可測試的。 但是你通過它調用的類和方法是。
我沒有看到scriplets特別糟糕,如果你遵循它的設計模式,我在spring mvc上工作很多,在我的jsp中,我只是在scriplits中獲取模型數據,並使用簡單的java代碼在html中向用戶顯示,我覺得它給了我比JSTL更多的自由。
這取決於您使用的模式。 通過使用MVC ( spring,struts,... ),您應該避免在JSP中使用scriptlet,因為它代表了應該包含純XHTML標記的視圖。 JSTL是一種聲明性語言,某種XML,而scriplet則不是。
特別是我通過原型使用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>
這是一個比較JSP和Facelets的表,它可能對某人有幫助,某處:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.