国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JSP > 正文

Template和JSP技術(shù)

2024-09-05 00:19:16
字體:
供稿:網(wǎng)友

最大的網(wǎng)站源碼資源下載站,

(本文發(fā)于java emag第一期)
一、起源與現(xiàn)狀:
關(guān)于template和jsp的起源還要追述到的遠(yuǎn)古年代,那個(gè)時(shí)候的人們用cgi來開發(fā)web應(yīng)用,在一個(gè)cgi程序中寫html標(biāo)簽。
在這之后世界開始朝不同的方向發(fā)展:sun公司提供了類似于cgi的servlet解決方案,但是無論是cgi還是servlet都面對(duì)同一個(gè)問題:在程序里寫html標(biāo)簽,無論如何都不是一個(gè)明智的解決方案。于是sun公司于1999年推出了jsp技術(shù)。而在另一個(gè)世界里,以php和asp為代表的scriptlet頁面腳本技術(shù)開始廣泛應(yīng)用。
不過即便如此,問題并沒有結(jié)束,新的問題出現(xiàn)了:業(yè)務(wù)和html標(biāo)簽的混合,這個(gè)問題不僅導(dǎo)致頁面結(jié)構(gòu)的混亂,同時(shí)也使代碼本身難以維護(hù)。
于是來自起源于70年代后期的mvc模式被引入開發(fā)。mvc的三個(gè)角色:model——包含除ui的數(shù)據(jù)和行為的所有數(shù)據(jù)和行為。view是表示ui中模型的顯示。任何信息的變化都由mvc中的第三個(gè)成員來處理——控制器。
在之后的應(yīng)用中,出現(xiàn)了技術(shù)的第一次飛躍:前端的顯示邏輯和后端的業(yè)務(wù)邏輯分離,com組件或ejb或corba用于處理業(yè)務(wù)邏輯,asp、jsp以及php被用于前端的顯示。這個(gè)就是的model 1階段(頁面控制器模式)。
不過這個(gè)開發(fā)模式有很多問題:
1.       頁面中必須寫入scriptlet調(diào)用組件以獲得所必需的數(shù)據(jù)。
2.       處理顯示邏輯上scriptlet代碼和html代碼混合交錯(cuò)。
3.       調(diào)試?yán)щy。jsp被編譯成servlet,頁面上的調(diào)試信息不足以定位錯(cuò)誤。
這一切都是因?yàn)樵趍odel 1中并沒有分離視圖和控制器。完全分離視圖和控制器就成了必須。這就是model 2。它把model 1中未解決的問題——分離對(duì)組件(業(yè)務(wù)邏輯)的調(diào)用工作,把這部分工作移植到了控制器?,F(xiàn)在似乎完美了,不過等等,原來的控制器從頁面中分離后,頁面所需的數(shù)據(jù)怎么獲得,誰來處理頁面顯示邏輯??jī)蓚€(gè)辦法:1. 繼續(xù)利用asp,php或者jsp等機(jī)制,不過由于它們是運(yùn)行在web環(huán)境下的,他們所要顯示的數(shù)據(jù)(后端邏輯產(chǎn)生的結(jié)果)就需要通過控制器放入request流中;2. 使用新手法——模板技術(shù),使用獨(dú)立的模板技術(shù)由于脫離的了web環(huán)境,會(huì)給開發(fā)測(cè)試帶來相當(dāng)?shù)谋憷V劣陧撁嫠钄?shù)據(jù)傳入一個(gè)pojo就行而不是request對(duì)象。
模板技術(shù)最先開始于php的世界,出現(xiàn)了phplib template和fasttemplate這兩位英雄。不久模板技術(shù)就被引入到j(luò)ava 世界里。目前比較流行的模板技術(shù)有:xstl,velocity,jdynamite,tapestry等。另外因?yàn)閖sp技術(shù)畢竟是目前標(biāo)準(zhǔn),相當(dāng)?shù)南到y(tǒng)還是利用jsp來完成頁面顯示邏輯部分,在sun公司的jstl外,各個(gè)第三方組織也紛紛推出了自己的taglib,一個(gè)代表是struts tablib。
二、 模板技術(shù)分析:
模板技術(shù)從本質(zhì)上來講,它是一個(gè)占位符動(dòng)態(tài)替換技術(shù)。一個(gè)完整的模板技術(shù)需要四個(gè)元素:0. 模板語言,1. 包含模板語言的模板文件,2. 擁有動(dòng)態(tài)數(shù)據(jù)的數(shù)據(jù)對(duì)象,3. 模板引擎。以下就具體討論這四個(gè)元素。(在討論過程中,我只列舉了幾個(gè)不同特點(diǎn)技術(shù),其它技術(shù)或有雷同就不重復(fù)了)
1.       模板語言:
模板語言包括:變量標(biāo)識(shí)和表達(dá)式語句。根據(jù)表達(dá)式的控制力不同,可以分為強(qiáng)控制力模板語言和弱控制力模板語言。而根據(jù)模板語言與html的兼容性不同,又可以分為兼容性模板語言和非兼容性模板語言。
模板語言要處理三個(gè)要點(diǎn):
1. 標(biāo)量標(biāo)記。把變量標(biāo)識(shí)插入html的方法很多。其中一種是使用類似html的標(biāo)簽;另一種是使用特殊標(biāo)識(shí),如velocity或者jdynamite;第三種是擴(kuò)展html標(biāo)簽,如tapestry。采用何種方式有著很多考慮,一個(gè)比較常見的考慮是“所見即所得”的要求。
2. 條件控制。這是一個(gè)很棘手的問題。一個(gè)簡(jiǎn)單的例子是某物流陪送系統(tǒng)中,物品數(shù)低于一定值的要高亮顯示。不過對(duì)于一個(gè)具體復(fù)雜顯示邏輯的情況,條件控制似乎不可避免。當(dāng)你把類似于<if condition=”$count <= 40”><then><span class=”highlight”>count </span></then></if>引入,就象我們當(dāng)初在asp和php中所做得一樣,我們將不得不再一次面對(duì)scriptlet嵌入網(wǎng)頁所遇到的問題。我相信你和我一樣并不認(rèn)為這是一個(gè)好得的編寫方式。實(shí)際上并非所有的模板技術(shù)都使用條件控制,很多已有的應(yīng)用如php上中的以及我曾見過一個(gè)基于asp.net的應(yīng)用,當(dāng)然還有java的jdynamite。這樣網(wǎng)頁上沒有任何邏輯,不過這樣做的代價(jià)是把高亮顯示的選擇控制移交給編程代碼。你必需做個(gè)選擇。也許你也象我一樣既不想在網(wǎng)頁中使用條件控制,也不想在代碼中寫html標(biāo)記,但是這個(gè)顯示邏輯是無可逃避的(如果你不想被你的老板抄魷魚的話),一個(gè)可行的方法是用css,在編程代碼中決定采用哪個(gè)css樣式。特別是css2技術(shù),其selector機(jī)制,可以根據(jù)html類型甚至是element的attributes來apply不同的樣式。
3. 迭代(循環(huán))。在網(wǎng)頁上顯示一個(gè)數(shù)據(jù)表單是一個(gè)很基本的要求,使用集合標(biāo)簽將不可避免,不過幸運(yùn)的是,它通常很簡(jiǎn)單,而且夠用。特別值得一提的是php的模板技術(shù)和jdynamite技術(shù)利用html的注釋標(biāo)簽很簡(jiǎn)單的實(shí)現(xiàn)了它,又保持了“所見既所得”的特性。
下面是一些技術(shù)的比較:
velocity
變量定義:用$標(biāo)志
表達(dá)式語句:以#開始
強(qiáng)控制語言:變量賦值:#set $this = "velocity"
            外部引用:#include ( $1 )
            條件控制:#if …. #end
非兼容語言
jdynamite
變量定義:用{}包裝
表達(dá)式語句:寫在注釋格式(<!--  à)中
弱控制語言
兼容語言
xslt
變量定義:xml標(biāo)簽
表達(dá)式:xsl標(biāo)簽
強(qiáng)控制語言:外部引用:import,include
            條件控制:if,  choose…when…otherwise
非兼容語言
tapestry
采用component的形式開發(fā)。
變量定義(組件定義):在html標(biāo)簽中加上jwcid
表達(dá)式語句:ognl規(guī)范
兼容語言
 
2.       模板文件:
模板文件指包含了模板語言的文本文件。
模板文件由于其模板語言的兼容性導(dǎo)致不同結(jié)果。與html兼容性的模板文件只是一個(gè)資源文件,其具有良好的復(fù)用性和維護(hù)性。例如jdynamite的模板文件不但可以在不同的項(xiàng)目中復(fù)用,甚至可以和php程序的模板文件互用。而如velocity的非兼容模板文件,由于其事實(shí)上是一個(gè)腳本程序,復(fù)用性和可維護(hù)性大大降低。
3.       擁有動(dòng)態(tài)數(shù)據(jù)的數(shù)據(jù)對(duì)象:
模板文件包含的是靜態(tài)內(nèi)容,那么其所需的動(dòng)態(tài)數(shù)據(jù)就需要另外提供。根據(jù)提供數(shù)據(jù)方式的不同可以分為3種:
1.       map:利用key/value來定位。這個(gè)是最常見的技術(shù)。如velocity的velocitycontext就是包含了map對(duì)象。
example.vm:
hello from $name in the $project project.
 
example.java:
velocitycontext context = new velocitycontext();
context.put("name", "velocity");
context.put("project", "jakarta");
 
2.       dom:直接操作dom數(shù)據(jù)對(duì)象,如xslt利用xpath技術(shù)。
3.       pojo:直接利用反射取得dto對(duì)象,利用javabean機(jī)制取得數(shù)據(jù)。如tapestry。
4.       模板引擎:
模板引擎的工作分為三步:
1. 取得模板文件并確認(rèn)其中的模板語言符合規(guī)范。
比如velocity,確定#if有對(duì)應(yīng)得#end等。xml+xslt的模型中,xml文件標(biāo)簽是否完整等。在完成這些工作后,模板引擎通常會(huì)把模板文件解析成一顆節(jié)點(diǎn)樹(包含模板文件的靜態(tài)內(nèi)容節(jié)點(diǎn)和模板引擎所定義的特殊節(jié)點(diǎn))。
2. 取得數(shù)據(jù)對(duì)象。
        該數(shù)據(jù)對(duì)象一般通過程序傳遞引用實(shí)現(xiàn)?,F(xiàn)有的大量框架在程序底層完成,處理方式也各自不同,有兩種技術(shù)分別為推技術(shù)和拉技術(shù)。推技術(shù):controller調(diào)用set方法把動(dòng)態(tài)數(shù)據(jù)注入,模板引擎通過get方法獲得,典型代表:struts;拉技術(shù):模板引擎根據(jù)配置信息,找到與view對(duì)應(yīng)的model,調(diào)用model的get方法取得數(shù)據(jù),典型代表:tapestry。
3. 合并模板文件(靜態(tài)內(nèi)容)和數(shù)據(jù)對(duì)象(動(dòng)態(tài)內(nèi)容),并生成最終頁面。
        合并的機(jī)制一般如下,模板引擎遍歷這顆節(jié)點(diǎn)樹的每一個(gè)節(jié)點(diǎn),并render該節(jié)點(diǎn),遇到靜態(tài)內(nèi)容節(jié)點(diǎn)按正常輸入,遇到特殊節(jié)點(diǎn)就從數(shù)據(jù)對(duì)象中去得對(duì)應(yīng)值,并執(zhí)行其表達(dá)式語句(如果有的話)。
以下詳細(xì)說明:
velocity
template template = velocity.gettemplate("test.wm");
context context = new velocitycontext();
context.put("foo", "bar");
context.put("customer", new customer());
template.merge(context, writer);
當(dāng)調(diào)用velocity.gettemplate 方法時(shí),將調(diào)用resourcemanger的對(duì)應(yīng)方法。
resourcemanger先查看該模板文件是否在cache中,如果沒有就去獲取,生成resource對(duì)象并調(diào)用process()方法,確定該模板是否有效,如果有效,則在內(nèi)存中生成一個(gè)node樹。
當(dāng)調(diào)用template.merge()時(shí),遍歷這顆node樹,并調(diào)用每個(gè)node的render方法。對(duì)于模板中的變量和對(duì)象node,還將調(diào)用execute()方法,從context中取得value。
   注:resourcemanger在runtime/resource包下,node在runtime/parser/node包下
tapestry
tapestry比較麻煩,先介紹一下http請(qǐng)求的處理過程。
當(dāng)httprequest請(qǐng)求到達(dá)時(shí)。該請(qǐng)求被applicationservlet捕獲,隨后applicationservlet通過getengine取到對(duì)應(yīng)的engine,通過該engine的getservice拿到對(duì)應(yīng)的service,調(diào)用其service方法執(zhí)行http請(qǐng)求。
每個(gè)service通過requestcycle對(duì)象的getpage方法取得page對(duì)象,并將其設(shè)置為該cycle對(duì)象的active page。之后service調(diào)用renderresponse方法執(zhí)行輸出。
renderresponse調(diào)用page的getresponsewriter(output)取得writer對(duì)象,并把它傳給cycle.renderpage(writer)方法,該方法調(diào)用page的renderpage方法。
page執(zhí)行renderpage時(shí),首先判斷是否有l(wèi)istener的請(qǐng)求,如果有則處理listener請(qǐng)求;然后調(diào)用basecomponenttemplateloader的process方法把模板文件載入并形成一個(gè)component節(jié)點(diǎn)樹,依次執(zhí)行節(jié)點(diǎn)的rendercomponent方法。
每個(gè)component對(duì)象將通過ongl的機(jī)制取得對(duì)象屬性。并把該值寫入輸入流。
例如:insert component
protected void rendercomponent(imarkupwriter writer, irequestcycle cycle) {
        if (cycle.isrewinding())
            return;
        object value = getvalue();
        if (value == null)
            return;
        string insert = null;
        format format = getformat();
        if (format == null) {
            insert = value.tostring();
        }
        else{
            try{
                insert = format.format(value);
            }
            catch (exception ex) {
                throw new applicationruntimeexception(
tapestry.format("insert.unable-to-format",value),this, getformatbinding().getlocation(), ex);
            }
        }
        string styleclass = getstyleclass();
        if (styleclass != null) {
            writer.begin("span");
            writer.attribute("class", styleclass);
            renderinformalparameters(writer, cycle);
        }
        if (getraw())
            writer.printraw(insert);
        else
            writer.print(insert);
        if (styleclass != null)
            writer.end(); // <span>
    }
getvalue為取得insert的value屬性。
 
三、jsp技術(shù)分析
       1. jsp技術(shù):
       jsp,一個(gè)偽裝后的servlet。web server會(huì)對(duì)任何一個(gè)jsp都生成一個(gè)對(duì)應(yīng)jsp類,打開這個(gè)類,就會(huì)發(fā)現(xiàn),jsp提供的是一個(gè)代碼生成機(jī)制,把jsp文件中所有的scriptlet原封不動(dòng)的copy的到生成的jsp類中,同時(shí)調(diào)用println把所有的html標(biāo)簽輸出。
test.jsp:
<html>
<head><title>jsp test</title></head>
<body>
<table width="226" border="0" cellspacing="0" cellpadding="0">
   <tr><td><font face="arial" size="2" color="#000066">
             <b class="headlinebold">the jsp test file</b>
       </tr></td> </font>  
</table>
<body>
</html>
test_jsp.java:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
 
public class test _jsp extends httpjspbase {
  private static java.util.vector _jspx_includes;
  public java.util.list getincludes() {
    return _jspx_includes;
  }
  public void _jspservice(httpservletrequest request, httpservletresponse response)
        throws java.io.ioexception, servletexception {
    jspfactory _jspxfactory = null;
    javax.servlet.jsp.pagecontext pagecontext = null;
    httpsession session = null;
    servletcontext application = null;
    servletconfig config = null;
    jspwriter out = null;
    object page = this;
    jspwriter _jspx_out = null;
 
    try {
      _jspxfactory = jspfactory.getdefaultfactory();
      response.setcontenttype("text/html;charset=iso-8859-1");
      pagecontext = _jspxfactory.getpagecontext(this, request, response, null, true, 8192, true);
      application = pagecontext.getservletcontext();
      config = pagecontext.getservletconfig();
      session = pagecontext.getsession();
      out = pagecontext.getout();
      _jspx_out = out;
 
      out.write("<html>/r/n");
      out.write("<head><title>jsp test</title></head> /r/n");
      out.write("<body>/r/n");
      out.write("<table width=/"226/" border=/"0/" cellspacing=/"0/" cellpadding=/"0/">/r/n   ");
      out.write("<tr><td><font face=/"arial /" size=/"2/" color=/"#000066/"> /r/n/t      ");
      out.write("<b class=/"headlinebold/">the jsp test file");
      out.write("</b>/r/n/t      ");
      out.write("</tr></td></font>/r/n/t ");
      out.write("</table>/r/n");
      out.write("<body>/r/n");
      out.write("</html>");
    } catch (throwable t) {
      out = _jspx_out;
      if (out != null && out.getbuffersize() != 0)
        out.clearbuffer();
      if (pagecontext != null) pagecontext.handlepageexception(t);
    } finally {
      if (_jspxfactory != null) _jspxfactory.releasepagecontext(pagecontext);
    }
  }
}
 
       2. taglib技術(shù):
taglib作為jsp之上的輔助技術(shù),其工作本質(zhì)依托與jsp技術(shù),也是自定義標(biāo)簽翻譯成java代碼,不過這次和jsp略有不同,它還要經(jīng)過幾個(gè)過程。
先來看一下,實(shí)現(xiàn)一個(gè)tag的2個(gè)要點(diǎn):
1. 提供屬性的set方法,此后這個(gè)屬性就可以在jsp頁面設(shè)置。以jstl標(biāo)簽為例 c:out value=""/,這個(gè)value就是jsp數(shù)據(jù)到tag之間的入口。所以tag里面必須有一個(gè)setvalue方法,具體的屬性可以不叫value。例如setvalue(string data){this.data = data;}。這個(gè)“value”的名稱是在tld里定義的。取什么名字都可以,只需tag里提供相應(yīng)的set方法即可。
2. 處理 dostarttag 或 doendtag 。這兩個(gè)方法是 tagsupport提供的。還是以c:out value=""/為例,當(dāng)jsp解析這個(gè)標(biāo)簽的時(shí)候,在“<”處觸發(fā) dostarttag 事件,在“>”時(shí)觸發(fā) doendtag 事件。通常在 dostarttag 里進(jìn)行邏輯操作,在 doendtag 里控制輸出。
  在處理tag的時(shí)候:
  0. 從tagpool中取得對(duì)應(yīng)tag。
1.     為該tag設(shè)置頁面上下文。
2.     為該tag設(shè)置其父tag,如果沒有就為null。
3.     調(diào)用setter方法傳入標(biāo)簽屬性值tag,如果該標(biāo)簽沒有屬性,此步跳過。
4.     調(diào)用dostarttag方法,取的返回值。
5.     如果該標(biāo)簽有body,根據(jù)dostarttag返回值確定是否pop該標(biāo)簽內(nèi)容。如果要pop其body,則:setbodycontent(),在之后,doinitbody()。如果該標(biāo)簽沒有body,此步跳過。
6.     調(diào)用doendtag()以確定是否跳過頁面剩下部分。
7.     最后把tag類返還給tagpool。
tag類為:
package my.customtags;
import javax.servlet.jsp.jspwriter;
import javax.servlet.jsp.pagecontext;
import javax.servlet.jsp.tagext.tagsupport;
 
public class hidden extends tagsupport{
    string name;  
    public hidden(){    name = "";    }
    public void setname(string name){    this.name = name;    }
    public void release(){   value = null;    }
    public int dostarttag(){  return eval_body_include;}
public int doendtag() throws jsptagexception{
   try{   pagecontext.getout().write(", you are welcome");   }
   catch(ioexception ex){   throw new jsptagexception("error!");    }
   return eval_page;
}
}
 
jsp頁面:
<my:hidden name="testname"/>
 
生成的jsp代碼:
my.customtags.hidden _jspx_th_my_hidden_11 = (my.customtags.hidden) _jspx_tagpool_my_hidden_name.get(my.customtags.hidden.class);
_jspx_th_my_hidden_11.setpagecontext(pagecontext);
_jspx_th_my_hidden_11.setparent(null);
_jspx_th_my_hidden_11.setname("testname");
int _jspx_eval_my_hidden_11 = _jspx_th_my_hidden_11.dostarttag();
if (_jspx_th_my_hidden_11.doendtag() == javax.servlet.jsp.tagext.tag.skip_page)
   return true;
_jspx_tagpool_my_hidden_name.reuse(_jspx_th_my_hidden_11);
return false;
 
   taglib技術(shù)提供兩個(gè)機(jī)制,body和non-body導(dǎo)致了taglib的出現(xiàn)了兩個(gè)分支:display tag和control tag, 前者在java code中嵌入了html標(biāo)簽,相當(dāng)與一個(gè)web component,而后者則是另一種模板腳本。
 
四、兩種技術(shù)方案的比較:
       1. 技術(shù)學(xué)習(xí)難易度
模板技術(shù)。使用模板技術(shù),第一點(diǎn)就是必須學(xué)習(xí)模板語言,尤其是強(qiáng)控制的模板語言。于是模板語言本身的友好性變的尤為重要。以下依據(jù)友好性,表現(xiàn)力以及復(fù)用性三點(diǎn)為主基點(diǎn)比較了一下幾種模板技術(shù)。
velocity:
turbine項(xiàng)目(http://jakarta.apache.org/turbine)采用了velocity技術(shù)。
1.       友好性不夠。理由: 強(qiáng)控制類型,出現(xiàn)頁面顯示控制代碼和html混合。與html的不兼容,無法所見即所得。遇到大的html頁面,從一個(gè) “#if”找到對(duì)應(yīng)的 “#end”也是很痛苦的一件事情。
2.       表現(xiàn)力強(qiáng)。理由:強(qiáng)控制語言。
3.       復(fù)用性弱。理由:模板腳本和頁面代碼混合。
xslt
cocoon項(xiàng)目(http://cocoon.apache.org/)采用xml + xslt的方法。csdn社區(qū)也是采用此方案。
1.       內(nèi)容和顯示風(fēng)格分離,這點(diǎn)xslt做的最好。
2.       速度慢。理由:xslt的使用xpath,由于是要解析dom樹,當(dāng)xml文件大時(shí),速度很慢。
3.       友好性不夠。理由:由于沒有html文件,根本看不到頁面結(jié)構(gòu)、顯示風(fēng)格和內(nèi)容。xsl語法比較難以掌握,由于沒有“所見即所得”編輯工具,學(xué)習(xí)成本高。
4.       表現(xiàn)力強(qiáng)。理由:強(qiáng)控制語言。
5.       復(fù)用性弱。理由:xsl標(biāo)簽和html標(biāo)簽混合。
jdynamite
1.       表現(xiàn)力中等。理由:弱控制語言。
2.       友好性強(qiáng)。理由:所見即所得的效果。在模板件中的ignore block在編輯條件下可展示頁面效果,而在運(yùn)行中不會(huì)被輸出。
3.       復(fù)用性強(qiáng)。理由:利用html標(biāo)簽。
tapestry
1.       友好性中等。理由:整個(gè)tapestry頁面文件都是html元素。但是由于component會(huì)重寫html標(biāo)簽,其顯示的樣子是否正確,將不預(yù)測(cè)。
2.       表現(xiàn)力強(qiáng)。理由:強(qiáng)控制語言。
3.       復(fù)用性強(qiáng)。理由:擴(kuò)展了html元素的定義。
 
 
在jsp中大量的使用taglib,能夠使得jsp的頁面結(jié)構(gòu)良好,更符合xml格式,而且能夠重用一些頁面元素。但taglib的編譯之后的代碼龐大而雜亂。tablib很不靈活,能完成的事情很有限。tablib代碼本身的可重用性受到tagsupport定義的限制,不是很好。 另外是,我不得不承認(rèn)的一件事是,taglib的編寫本身不是一件愉快的事情,事實(shí)我個(gè)人很反對(duì)這種開發(fā)方式。
 
       2. 技術(shù)使用難易度
       模板技術(shù):模板技術(shù)本身脫離了web環(huán)境,可以在不啟動(dòng)web server得情況下進(jìn)行開發(fā)和測(cè)試,一旦出錯(cuò)詳細(xì)的信息易于錯(cuò)誤的定位。由于模板引擎的控制,頁面中將只處理顯示邏輯(盡管其可能很復(fù)雜)
       jsp技術(shù):工作在web環(huán)境下,開發(fā)測(cè)試一定要運(yùn)行web server。此外,一些taglib能夠產(chǎn)生新的標(biāo)簽,頁面的最終布局也必須在web環(huán)境下才可以確定。測(cè)試時(shí)出錯(cuò)信息不明確,特別是taglib得存在,極不容易定位。由于其本質(zhì)是程序,很容易在其中寫入業(yè)務(wù)邏輯,甚至于數(shù)據(jù)庫連接代碼,造成解耦的不徹底。
 
3. 總結(jié)
模板技術(shù)更加專注于頁面的顯示邏輯,有效幫助開發(fā)人員分離視圖和控制器。在學(xué)習(xí),開發(fā)和測(cè)試都更加容易。
jsp技術(shù)本身是一個(gè)早期的技術(shù),本身并沒有提出足夠的方式來分離視圖和控制器。相反,我認(rèn)為其本身是鼓勵(lì)開發(fā)人員不做解耦,因?yàn)樵趈sp代碼中插入業(yè)務(wù)邏輯是如此的容易。
上一篇:JSP與JavaBean詳談

下一篇:JSP問答

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 昭苏县| 丰宁| 柏乡县| 应城市| 许昌县| 太谷县| 仁布县| 望江县| 绿春县| 驻马店市| 崇文区| 华亭县| 贵德县| 南江县| 营山县| 洪江市| 浙江省| 武鸣县| 贞丰县| 田东县| 阿拉善盟| 察哈| 云和县| 枣阳市| 财经| 运城市| 吉水县| 长顺县| 晋宁县| 黄平县| 错那县| 安岳县| 浏阳市| 黎平县| 辉县市| 兴城市| 遂溪县| 依安县| 水城县| 洮南市| 桐乡市|