答案:
--2种Model I方式:和Model II Lance Lavandowska
作者: blueski
编译:
Servlet
如果你经常去或JSP的Model I 新闻组或者邮件列表,那么一定会看到不少关于和Model II 方OOP法的讨论。究竟采用哪一种,这取决于你的个人喜好、团队工作策略以及是否采用正统的。 Model I
简单地说,将business logic事务逻辑()presentation code和表示代码()HTML融合在一起(如在中Model II);则 提倡最大限度地将所有的代码放到内容表示之外。 Model I
: 简 单的单层次应用 Java
如果是在一个人人都精通和HTML的HTML环境中,或者你独自做着所有的工作,假如每个人都有清晰的编程结构和思路,那么这种方易做图很有效,不过这样的假设不在本文讨论范围之内。这种方法的第一个优点是如果你的应用改变了,你只需维护一个文件。而最大的缺陷是可读性!除非十分小心,否则你的和Java代 码会相互混杂,从而难以维护。 TimeZone
在下面这个例子中,我们将增加一个元JSP素,从而使它变成文TimeZone件,它会返回基于时间的所期待的。 TimeZone如果没有提交, 那么缺省的是服务器的缺省时间。
====================================================================== 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
相应地,数据也可以从取 得并加以显示。在下一个例子中我们就可以看到。 Model II
: 重Redirecting Requests定向请求() HTML
在一个团队开发环境中,有些是设Java计者,另一些则是程Java序员,这时这一方法显得非常重要。程HTML序员可以集中精力创建可重用代码,而设 计师可以集中精力于内容表示,彼此相对对立,可以分别动态地修改自己的内容,只要总体的输入输出不变。 Model II
现在我们可以使用来Model I表示的Model-View-Controller 那个例子。这一方法遵循了(MVC) 范 例(cite Design Patterns book) 。在servlet这个例子中,我们只有一个类(页或者) 处Controller理请求()TimeZone,取得,View设置所有用于表示的变量,并将控制传递到表示页() 。作为如此简单的应用,可以没有"Model" 。 Controller
: timeByZone.jsp controller
可servlet以是一个或JSP一个页JSP。我推荐使用,granularity因为这样我不必担心每当我做修改时要对类重新编译,但是,你将因此失去( 颗粒性),以后要扩展该类也比较困难。
====================================================================== 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
第二种方法(在内部使用了代码)可能有些笨重,但允许开发者确保输出不至于很糟糕(例如":null:null null"Session bean),假定还 没有被实例化以及没有进行值的设置。这View种情况发生在客户端直接调用了页scriptlets。问题是使用脚本可url以允许更强的控制。如果你确信你可以控制存bean取,那么方 View法当然更适合于开发,并使页HTML更方便于设 计者的协同工作。 Model II
上面的是"传统的"设Session计。所有的变量都包装了并放在对2象中。这有个 不足: 1
) 如Session果客户端拒绝参与的话,是 不可得到的。 2
) 除Session非变Session量被显式地移走,否则它回一直存在,直到被 破坏或过期。 cookies
第一种案例很可能发生在这样的场合,即使用了作mechanism为声明的结构()form而开发者没有能够提供声明的结构的替代表单()URL,即改 写。 Sessions
第二个案例甚至更为严重,因为它可能引起很大的内存消耗,如果被30定义为保存比标准存留时间更长的话((标准存留时间是分30钟)。即使是分Session钟的,Model这种也Session可能在大的应用中引起灾难性的内存泄露。为什么呢?在对Session象内部设置的对象被实例化了,并且在终references止以前一直没有被移去。因为它们仍然有关联(Session对 象)指garbage-collected向它们,所以无法被垃圾收集()Model II 。在模Session型中,很多对象被放到中JavaBean(要么直接地,要么通过)Session。随着的Session进行,更多的页被存取,内存使用会增加并持续下去直到客户端终止了或Session者过Session期。要一直等到变. 得非法,放在那的对象才能被垃圾收集,而那些损失的内存本可以用于任何其它的用途。 Beans
改进的方法之一是将或Request者其它变量放到对RequestDispatcher.include象中去,并使用(RequestDispatcher.forward)而不是(View )。这样做以后,页Controller具有和一Model II样的存取请求的对象。传统的设 计的不足可以被排除。 Model II
一个最后的评注:尽管有如上所述,我个人仍有些不喜欢的 范例,如果它用通常方法开
上一个:JSP简明教程:令人兴奋的脚本编程
下一个:在JSP中定义函数