明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

JSP構(gòu)架

[摘要]--2種Model I方式:和Model II Lance Lavandowska 作者: blueski 編譯:   Servlet如果你經(jīng)常去或JSP的Model I 新聞組或者郵件列表,那么一定會看到不少關(guān)于和Model II 方OOP法的討論。究竟采用哪一種,這取決于你的個人喜好、團(tuán)隊工作...

--2種Model I方式:和Model II Lance Lavandowska





作者: blueski



編譯:



  Servlet



如果你經(jīng)常去或JSP的Model I 新聞組或者郵件列表,那么一定會看到不少關(guān)于和Model II 方OOP法的討論。究竟采用哪一種,這取決于你的個人喜好、團(tuán)隊工作策略以及是否采用正統(tǒng)的。 Model I



簡單地說,將business logic事務(wù)邏輯()presentation code和表示代碼()HTML融合在一起(如在中Model II);則 提倡最大限度地將所有的代碼放到內(nèi)容表示之外。 Model I





: 簡 單的單層次應(yīng)用 Java



如果是在一個人人都精通和HTML的HTML環(huán)境中,或者你獨自做著所有的工作,假如每個人都有清晰的編程結(jié)構(gòu)和思路,那么這種方法會很有效,不過這樣的假設(shè)不在本文討論范圍之內(nèi)。這種方法的第一個優(yōu)點是如果你的應(yīng)用改變了,你只需維護(hù)一個文件。而最大的缺陷是可讀性!除非十分小心,否則你的和Java代 碼會相互混雜,從而難以維護(hù)。 TimeZone



在下面這個例子中,我們將增加一個元JSP素,從而使它變成文TimeZone件,它會返回基于時間的所期待的。 TimeZone如果沒有提交, 那么缺省的是服務(wù)器的缺省時間。



====================================================================== xml version

<=1.0"" ? > H1

<>Time JSP<H1> jsp

<:scriptlet> the parameter

//"zone" shall be equal to a number between 0 and 24 (inclusive) TimeZone timeZone

= TimeZone.getDefault( );/returns the default TimeZone for the server / if

(request.getParameterValues(zone"" )! null=)

{ String timeZoneArg

= request.getParameterValues(zone""0)[] ; timeZone

= TimeZone.getTimeZone(GMT"+ "+ timeZoneArg + "00:" ); gets a TimeZone. For this example we

//'re just going to assume its a positive argument

//, not a negative one.

} since we

//'re basing our time from GMT, we'll set our Locale to Brittania, and get a Calendar. Calendar myCalendar

= Calendar.getInstance(timeZone, Locale.UK) ; jsp

</:scriptlet> myCalendar.get

<%=(Calendar.HOUR_OF_DAY) % >: myCalendar.get

<%=(Calendar.MINUTE) % >: myCalendar.get

<%=(Calendar.SECOND) % >

====================================================================== JavaBean

相應(yīng)地,數(shù)據(jù)也可以從取 得并加以顯示。在下一個例子中我們就可以看到。 Model II





: 重Redirecting Requests定向請求() HTML





在一個團(tuán)隊開發(fā)環(huán)境中,有些是設(shè)Java計者,另一些則是程Java序員,這時這一方法顯得非常重要。程HTML序員可以集中精力創(chuàng)建可重用代碼,而設(shè) 計師可以集中精力于內(nèi)容表示,彼此相對對立,可以分別動態(tài)地修改自己的內(nèi)容,只要總體的輸入輸出不變。 Model II



現(xiàn)在我們可以使用來Model I表示的Model-View-Controller 那個例子。這一方法遵循了(MVC) 范 例(cite Design Patterns book) 。在servlet這個例子中,我們只有一個類(頁或者) 處Controller理請求()TimeZone,取得,View設(shè)置所有用于表示的變量,并將控制傳遞到表示頁() 。作為如此簡單的應(yīng)用,可以沒有"Model" 。 Controller



: timeByZone.jsp controller





可servlet以是一個或JSP一個頁JSP。我推薦使用,granularity因為這樣我不必?fù)?dān)心每當(dāng)我做修改時要對類重新編譯,但是,你將因此失去( 顆粒性),以后要擴(kuò)展該類也比較困難。





====================================================================== xml version

<=1.0"" ? > --Worker Class

<!, nobody should see me--> jsp

<:scriptlet> the parameter

//"zone" shall be equal to a number between 0 and 24 (inclusive) TimeZone timeZone

= TimeZone.getDefault( );/returns the default TimeZone for the server / if

(request.getParameterValues(zone"" )! null=)

{ String timeZoneArg

= request.getParameterValues(zone""0)[] ; timeZone

= TimeZone.getTimeZone(GMT"+ "+ timeZoneArg + "00:" ); gets a TimeZone. For this example we

//'re just going to assume its a positive argument

//, not a negative one.

} TimeBean timeBean

= new TimeBean( ); timeBean.setHours

= myCalendar.get(Calendar.HOUR_OF_DAY) ; timeBean.setMinutes

= myCalendar.get(Calendar.MINUTE) ; timeBean.setSeconds

= myCalendar.get(Calendar.SECOND) ; HttpSession mySession

= request.getSession( ); mySession.putValue

(tempTimeBean"" timeBean,) ; jsp



</:scriptlet> jsp

<:forward page=displayTime.jsp"" / >

====================================================================== View





: displayTime.jsp view





同樣地,這個既servlet可以是一個也jsp可以是一個文Session件。這里我們從中Bean取得并顯示它的值。實際上我們會將這做兩次,來示范是 如何被使用的。



====================================================================== xml version

<=1.0"" ? > H1

<>Time JSP<H1> jsp

<:useBean class=TimeBean"" id=tempTimeBean"" scope=session"" / > jsp

<:getProperty name=tempTimeBean"" property=hours"" >: jsp

<:getProperty name=tempTimeBean"" property=minutes"" >: jsp

<:getProperty name=tempTimeBean"" property=seconds"" > -- these would have printed

<!"null" if tempTimeBean was not instantiated by timeByZone.jsp --> jsp



<:scriptlet> HttpSession mySession

= request.getSession( ); TimeBean timeBean

= mySession.getValue(tempTimeBean"" ); if

(timeBean ! null=)

{/ check to make sure its not null/, to avoid NullPointerExceptions out.print

(timeBean.getHours( )); out.print

( ":"); out.print

(timeBean.getMinutes( )); out.print

( ":"); out.print

(timeBean.getSeconds( ));

} else



{ out.println

(Press your Back button and select a TimeZone"" );

} jsp

</:scriptlet>

====================================================================== null

第二種方法(在內(nèi)部使用了代碼)可能有些笨重,但允許開發(fā)者確保輸出不至于很糟糕(例如":null:null null"Session bean),假定還 沒有被實例化以及沒有進(jìn)行值的設(shè)置。這View種情況發(fā)生在客戶端直接調(diào)用了頁scriptlets。問題是使用腳本可url以允許更強的控制。如果你確信你可以控制存bean取,那么方 View法當(dāng)然更適合于開發(fā),并使頁HTML更方便于設(shè) 計者的協(xié)同工作。 Model II





上面的是"傳統(tǒng)的"設(shè)Session計。所有的變量都包裝了并放在對2象中。這有個 不足: 1



) 如Session果客戶端拒絕參與的話,是 不可得到的。 2



) 除Session非變Session量被顯式地移走,否則它回一直存在,直到被 破壞或過期。 cookies



第一種案例很可能發(fā)生在這樣的場合,即使用了作mechanism為聲明的結(jié)構(gòu)()form而開發(fā)者沒有能夠提供聲明的結(jié)構(gòu)的替代表單()URL,即改 寫。 Sessions



第二個案例甚至更為嚴(yán)重,因為它可能引起很大的內(nèi)存消耗,如果被30定義為保存比標(biāo)準(zhǔn)存留時間更長的話((標(biāo)準(zhǔn)存留時間是分30鐘)。即使是分Session鐘的,Model這種也Session可能在大的應(yīng)用中引起災(zāi)難性的內(nèi)存泄露。為什么呢?在對Session象內(nèi)部設(shè)置的對象被實例化了,并且在終references止以前一直沒有被移去。因為它們?nèi)匀挥嘘P(guān)聯(lián)(Session對 象)指garbage-collected向它們,所以無法被垃圾收集()Model II 。在模Session型中,很多對象被放到中JavaBean(要么直接地,要么通過)Session。隨著的Session進(jìn)行,更多的頁被存取,內(nèi)存使用會增加并持續(xù)下去直到客戶端終止了或Session者過Session期。要一直等到變. 得非法,放在那的對象才能被垃圾收集,而那些損失的內(nèi)存本可以用于任何其它的用途。 Beans



改進(jìn)的方法之一是將或Request者其它變量放到對RequestDispatcher.include象中去,并使用(RequestDispatcher.forward)而不是(View )。這樣做以后,頁Controller具有和一Model II樣的存取請求的對象。傳統(tǒng)的設(shè) 計的不足可以被排除。 Model II



一個最后的評注:盡管有如上所述,我個人仍有些不喜歡的 范例,如果它用通常方法開發(fā)的話。客 戶端被引送到某一個地址,然后又被轉(zhuǎn)向到另一個不同的類,我不喜歡創(chuàng)建這樣的系統(tǒng);谶@樣的原因,我修改了設(shè)計,使它變成了以下的樣子: Controller



: timeByZone2.jsp controller





和前面一樣,使Request用值View來取得必要的數(shù)據(jù),并且將數(shù)據(jù)放到請求的對象中去。這回的區(qū)別是頁RequestDispatcher.include將使用(Controller)來調(diào)用。chained在這種方法中,客戶端再也不做重定向,請求不是"鏈接”class的。相當(dāng)于/jsp請 求了另一方來為它做一些工作,然后繼續(xù)。



====================================================================== xml version

<=1.0"" ? > --Worker Class

<!, nobody should see me--> jsp

<:scriptlet> the parameter

//"zone" shall be equal to a number between 0 and 24 (inclusive) TimeZone timeZone

= TimeZone.getDefault( );/returns the default TimeZone for the server / if

(request.getParameterValues(zone"" )! null=)

{ String timeZoneArg

= request.getParameterValues(zone""0)[] ; timeZone

= TimeZone.getTimeZone(GMT"+ "+ timeZoneArg + "00:" ); gets a TimeZone. For this example we

//'re just going to assume its a positive argument

//, not a negative one.

} TimeBean timeBean

= new TimeBean( ); timeBean.setHours

= myCalendar.get(Calendar.HOUR_OF_DAY) ; timeBean.setMinutes

= myCalendar.get(Calendar.MINUTE) ; timeBean.setSeconds

= myCalendar.get(Calendar.SECOND) ; request.setAttribute

(tempTimeBean"" timeBean,) ; jsp

</:scriptlet>

====================================================================== View





: displayTime2.jsp displayTime.jsp





和非timeByZone2.jsp常相似,但在 也的頂部被調(diào)用。請注意<jsp:useBean / >中scope的""request已經(jīng)被換成了"" 。



====================================================================== xml version

<=1.0"" ? > H1

<>Time JSP<H1> jsp



<:include page=timeByZone2.jsp"" / > jsp



<:useBean class=TimeBean"" id=tempTimeBean"" scope=request"" / > jsp

<:getProperty name=tempTimeBean"" property=hours"" >: jsp

<:getProperty name=tempTimeBean"" property=minutes"" >: jsp

<:getProperty name=tempTimeBean"" property=seconds"" > -- these would have printed

<!"null" if tempTimeBean was not instantiated by timeByZone2.jsp -->



====================================================================== View





在一個在建系統(tǒng)中,我們已經(jīng)使用這種方法來創(chuàng)建類的鏈,每一個都只對它所處理的工作負(fù)責(zé)。通過辨別公用的表示格式,我們創(chuàng)建了一個對JSP象,即使在很高層次的中 它也可以重復(fù)使用。我們的目標(biāo)就是建立一些可重用的頁,同時減少用于表示的類的數(shù)量。 Servlet Model



單個的(A Model II Design)





什么時候我有足夠時間來研究這個課題,我會在這里發(fā)表更多的東西。



附原文: JSP Architectures



An explanation and comparison of the methodologies

commonly known as

"Model I" and "Model II". Lance Lavandowska To Outline

If you spend any time reading through Servlet or JSP related newsgroups or mailing lists



, you're likely to encounter a discussion of Model I versus Model II methodologies . Which one you use depends on personal taste, team work strategies and OOP orthodoxy. Loosely described



, Model I is an approach where business logic and presentation code can be intermixed with the presentation itself (HTML in our arena). Model II proscribes that all code, to the extent this is possible, be excluded from the presentation. Model I



: Simple 2 1/2 Tier Application In a team environment where everyone knows Java and HTML

, or if you're doing it all yourself, this approach can work well, provided everyone maintains a clear coding structure (that discussion is outside the bounds of this article). The primary advantage of this approach is that there is only one file to maintain for changes to your application. The major disadvantage is readability! Unless great care is taken, your HTML and Java code can become so intermingled that it becomes difficult to debug and maintain your application. For this example



, we are going to revisit the "Sample Page" from the JSP Quick Start chapter. I'm going to add a TimeZone element, so we'll have a JSP that returns the time based on the desired timezone. If no TimeZone is submitted, we'll default to that of the server.



====================================================================== xml version

<=1.0"" ? > H1

<>Time JSP<H1> jsp

<:scriptlet> the parameter

//"zone" shall be equal to a number between 0 and 24 (inclusive) TimeZone timeZone

= TimeZone.getDefault( );/returns the default TimeZone for the server / if

(request.getParameterValues(zone"" )! null=)

{ String timeZoneArg

= request.getParameterValues(zone""0)[] ; timeZone

= TimeZone.getTimeZone(GMT"+ "+ timeZoneArg + "00:" ); gets a TimeZone. For this example we

//'re just going to assume its a positive argument

//, not a negative one.

} since we

//'re basing our time from GMT, we'll set our Locale to Brittania, and get a Calendar. Calendar myCalendar

= Calendar.getInstance(timeZone, Locale.UK) ; jsp

</:scriptlet> myCalendar.get

<%=(Calendar.HOUR_OF_DAY) % >: myCalendar.get

<%=(Calendar.MINUTE) % >: myCalendar.get

<%=(Calendar.SECOND) % >

====================================================================== Similarly

, the data to be displayed could have been gotten from a JavaBean. We'll see a little of that in the next example. Model II

: Redirecting Requests In a team environment where some members are HTML designers and others are Java programmers

, this approach can be particularly strong. The Java programmers can focus on creating (re)usable code, while the HTML designers can focus on presentation. While the two remain dependant on each other, one or the other can change dramatically so long as the principle inputs and outputs (respectively) remain the same. Now we



'll take the same desired behaviour from the Model I example, and present it using the Model II methodology. This methodology follows the Model-View-Controller (MVC) paradigm (cite Design Patterns book). For this example, we'll have one class (or page or servlet) process the request (Controller) get the TimeZone,, set all the required variables for presentation, and pass control off to a presentation page (View). For simple apps like this, there is no "Model". Controller



: timeByZone.jsp The controller can be a servlet or a jsp file. I prefer to use JSP

, as I don't have to worry about compiling the class each time I make changes. However, you lose granularity this way, and make it more difficult to extend this class later (we'll review this in Advanced JSP Programming).



====================================================================== xml version

<=1.0"" ? > --Worker Class

<!, nobody should see me--> jsp

<:scriptlet> the parameter

//"zone" shall be equal to a number between 0 and 24 (inclusive) TimeZone timeZone

= TimeZone.getDefault( );/returns the default TimeZone for the server / if

(request.getParameterValues(zone"" )! null=)

{ String timeZoneArg

= request.getParameterValues(zone""0)[] ; timeZone

= TimeZone.getTimeZone(GMT"+ "+ timeZoneArg + "00:" ); gets a TimeZone. For this example we

//'re just going to assume its a positive argument

//, not a negative one.

} TimeBean timeBean

= new TimeBean( ); timeBean.setHours

= myCalendar.get(Calendar.HOUR_OF_DAY) ; timeBean.setMinutes

= myCalendar.get(Calendar.MINUTE) ; timeBean.setSeconds

= myCalendar.get(Calendar.SECOND) ; HttpSession mySession

= request.getSession( ); mySession.putValue

(tempTimeBean"" timeBean,) ; jsp



</:scriptlet> jsp

<:forward page=displayTime.jsp"" / >

====================================================================== View

: displayTime.jsp Again

, the view can be either a servlet or a jsp file. Here we'll get the Bean from the Session, and display its values. We'll actually do this twice, to illustrate again how Beans are used.





====================================================================== xml version

<=1.0"" ? > H1

<>Time JSP<H1> jsp

<:useBean class=TimeBean"" id=tempTimeBean"" scope=session"" / > jsp

<:getProperty name=tempTimeBean"" property=hours"" >: jsp

<:getProperty name=tempTimeBean"" property=minutes"" >: jsp

<:getProperty name=tempTimeBean"" property=seconds"" > -- these would have printed

<!"null" if tempTimeBean was not instantiated by timeByZone.jsp --> jsp



<:scriptlet> HttpSession mySession

= request.getSession( ); TimeBean timeBean

= mySession.getValue(tempTimeBean"" ); if

(timeBean ! null=)

{/ check to make sure its not null/, to avoid NullPointerExceptions out.print

(timeBean.getHours( )); out.print

( ":"); out.print

(timeBean.getMinutes( )); out.print

( ":"); out.print

(timeBean.getSeconds( ));

} else



{ out.println

(Press your Back button and select a TimeZone"" );

} jsp

</:scriptlet>

====================================================================== The second method

(using code inside) may be more cumbersome, but allows the developer to ensure against ugly output (such as "null:null:null null" if the Session bean has not been instantiated )& had its values set. This would likely only happen if the client somehow called the View page directly. The point is that using scriptlets allows for greater control. If you are certain you can control url access, the bean approach certainly eases development, and makes the View page easier for HTML designers to work with. The above is the



"traditional" Model II design. You'll note that all the variables are wrapped up and placed into the Session object. This has two weaknesses: 1) no Session is availabe because the client has refused to participate, 2) unless the Session variable is explicitly removed it will continue to exist until the Session is destroyed or expires. The first case is most likely to happen when cookies are used as the State mechanism and the developers have failed to provide for the alternative form of State maintenance



, URL rewriting. The second case is even more serious



, as it can lead to great memory use if Sessions are defined to exist for more than the standard amount of time (30 minutes appears to be the standard). Even in the case of 30 minute Sessions, this Model can lead to disastrous memory leaks in systems under great use. Why? Objects get instantiated, set inside the Session object, and are not removed until the Session ends. Because they still have references (the Session object) pointing to them, they are not garbage-collected. In the Model II pattern, many objects are placed into the Session (either directly or via a JavaBean). As the Session progresses (more pages are accessed) memory-use increases and persists until the client ends the Session or the Session times out. Until the Session is invalidated, the objects placed there cannot be garbage-collected, and thus consume memory that could be of use elsewhere. One means of addressing this issue is to place the Beans or other variables into the Request object



, and use RequestDispatcher.include( rather than RequestDispatcher.forward)(. By doing so), the View page has access to the same Request object as the Controller, and the weaknesses of the traditional Model II design are obviated. One final comment



: despite all the above, I have a personal distaste for the Model II paradigm as it is commonly implemented. The creation of a system where the client is sent to an address, but is redirected to a different class, is for some reason abhorrent to me. For this reason, I've modified the design in the following manner: Controller



: timeByZone2.jsp As before

, the controller uses the Request values to obtain the necessary data and put that data into the Request object. The difference this time is that the View page will call the Controller using RequestDispatcher.include(. In this way), the client is never redirected, and Requests are not "chained". Rather, the class/jsp called asks someone else to do some work for it, then continues.



====================================================================== xml version

<=1.0"" ? > --Worker Class

<!, nobody should see me--> jsp

<:scriptlet> the parameter

//"zone" shall be equal to a number between 0 and 24 (inclusive) TimeZone timeZone

= TimeZone.getDefault( );/returns the default TimeZone for the server / if

(request.getParameterValues(zone"" )! null=)

{ String timeZoneArg

= request.getParameterValues(zone""0)[] ; timeZone

= TimeZone.getTimeZone(GMT"+ "+ timeZoneArg + "00:" ); gets a TimeZone. For this example we

//'re just going to assume its a positive argument

//, not a negative one.

} TimeBean timeBean

= new TimeBean( ); timeBean.setHours

= myCalendar.get(Calendar.HOUR_OF_DAY) ; timeBean.setMinutes

= myCalendar.get(Calendar.MINUTE) ; timeBean.setSeconds

= myCalendar.get(Calendar.SECOND) ; request.setAttribute

(tempTimeBean"" timeBean,) ; jsp

</:scriptlet>

====================================================================== View

: displayTime2.jsp Much like displayTime.jsp

, however you'll see that timeByZone2.jsp is called at the top of the page. Notice that the scope of <jsp:useBean / has changed to >"request".



====================================================================== xml version

<=1.0"" ? > H1

<>Time JSP<H1> jsp



<:include page=timeByZone2.jsp"" / > jsp



<:useBean class=TimeBean"" id=tempTimeBean"" scope=request"" / > jsp

<:getProperty name=tempTimeBean"" property=hours"" >: jsp

<:getProperty name=tempTimeBean"" property=minutes"" >: jsp

<:getProperty name=tempTimeBean"" property=seconds"" > -- these would have printed

<!"null" if tempTimeBean was not instantiated by timeByZone2.jsp -->



====================================================================== In a system currently under construction

, we've made use of this method to create chains of classes, each responsible for its own processing. By identifying common presentation formats, we've created View objects that can be reused in yet higher level JavaServer Pages. Our goal is to create pages that are designed for reuse, and to reduce the number of presentation classes. Single Servlet Model



(A Model II Design) When I

've had time to adequately research and implement this idea, I'll post something here.




標(biāo)簽:JSP構(gòu)架 

相關(guān)文章