Servlets 与JSP,最佳实践
作者:Qusay H.Mahmoud
2003年3月
Java Servlet技术与JSP技术使Java服务器端技术,目前他们控制了整个服务器端Java技术市场,并且逐渐成为构建商业Web应用的标准。Java开发者喜欢这些技术是由于很多的原因,包括:这些技术很容易学习,一次编写,处处运行(Write Once, Run Anywhere)。更重要的是,如果更高效的采用了下面的实践,Servlet与JSP能够帮助分开Web的表示与内容。“最佳实践”是被证明为开发高质量、可重用与易维护的基于Servlet和JSP的Web应用的较好方法。与此相对应的是,将Java代码混合在HTML中,这样很容易产生低效率、不易重用、难于维护的复杂应用程序。最佳实践将改变这些弊端。
在这篇文章中,我将描述为Servlets与JSP准备的最佳实践的重要性;这里我假想读者已经了解两者的基本工作原理。这篇文章将涵盖以下内容:
l 简要介绍Java Servlet与JavaServer Pages (JSP)
l 为开发Servlets 与JSP提供一些提示,技巧与规则。
l 为Servlet与JSP提供最佳实践
概述:关于Servlets与JSP Pages
类似于公共网关接口(Common Gateway Interface, CGI)脚本,Servlet提供了一种请求/响应的编程模型。当客户机向服务器提交一个请求(Request)时,服务器向Servlet提交了这个请求,然后Servlet构造了一个响应(Response),这个响应被服务器返回给客户。与CGI脚本不同的是,Servlet与HTTP服务器运行在同一个进程中。
当客户机的请求建立的时候,方法service方法被调用,并且传递给Request类和Response类。Servlet首先检查该请求的类型为GET或者POST,然后根据情况调用doGet或者doPost。如果请求的类型为GET, 则调用doGet方法,否则调用doPost。两种方法都接受两个参数:request(HttpServletRequest)和response(HttpServletResponse)。
在最简单的情况下,servlets与Java中的类可以利用print方法来产生动态的网页。对servlet而言重要的是,他们必须运行在容器中,容器提供对各种类的生命周期的管理。因此,编写Servlet可以从Java平台中得到所有的Java的好处,例如“砂箱模型(安全)”, 用JDBC进行数据库操作,跨平台特性等。
JavaServer Pages (JSP)
JSP技术是Servlet技术的一个较高层次的抽象。它是Sun公司开发、开放的技术,是与Microsoft公司的ASP动态网页技术相似的一种技术,并且它是Java2 企业版(J2EE)的一个关键组件。目前,很多商业的应用服务器(例如BEA WebLogic, IBM WebSphere, Live JRun, Orion等等)都支持JSP。
JSP如何工作?
一个JSP页面基本上来自于一个传统的HTML和一些Java代码的混合,并且以.jsp作为文件名后缀。这样告诉服务器这个页面需要特殊的处理以实现动态网页。
当一个JSP页面被读取时,他首先将被编译(JSP引擎来做这件事情)为一个Servlet。 这时候这个Servlet就像其他Servlet一样被交给Servlet引擎来处理。然后Servlet引擎读取那个Servlet对应的类(用ClassLoader)并且执行它,产生一个动态HTML页面(图1)。这个Servlet创建一些必需的元件, 然后将这些元件作为一个字符串写入输出流(OutputStream),并显示在浏览器中。
图1
下一次这个页面被请求的时候,除非这个页面被改变了, 否则JSP引擎只运行已经产生了的Servlet。如果页面改变了,JSP引擎就自动编译这个jsp文件成为一个Servelt并运行.
最佳实践
在这一部分中,我将描述在Servelt, 特别是JSP中的最佳实践。强调JSP是因为JSP比Servlet得到更为广泛的应用(也许是因为JSP技术促进了表示与逻辑的分离)。一个集成Servlet与JSP的最佳实践是“模型-显示-控制器”设计模式(Model View Controller, MVC), 他将在文章的后面一部分讨论。
l 不要在HTML页面中过度使用Java代码:将所有的Java代码直接放在JSP页面中,对于小项目而言没有问题,但是过度使用将会导致意大利面条似的代码,难于阅读,难于理解。减少Java代码的方法是编写独立的Java类来实现计算等逻辑。
l 采用合适的include 机制: 静态的数据,例如页眉,页角,导航条等,最好放在单独的文件中,并且不需要自动的重新产生。一旦他们被独立开来,你可以用下面的两种机制中的一种来包含,是指在所有页面中有一致的外观:
1. 使用include 指令: <%@ include file=”filename”%>
2. 使用行为: <jsp:include page=”page.jsp” flush=”true”/>
第一种机制,当JSP正在转换成Servlet时,将包含的指定文件的内容,这个操作由Servlet引擎完成;第二种机制,当该页面执行后时,页面包含了用Response产生的内容。当被包含的页面不太改变的时候,我推荐使用第一种方式,这种方式比较快;当被包含的文件经常改变(其中也有动态内容)时,使用第二种方式。
另外一种包含机制是使用JSP标准标记库(JSTL)中的<c:import>的行为标记。你可以使用这种方式来包含本地的或者远程的文件,例子如下:
<c:import url=”./copyright.html”/>
<c:import url=http://www.somewhere.com/hello.xml />
l 不要将逻辑与表示混在一起:在更为复杂的应用中,并且更多的代码被引入时,很重要的一点是不要将逻辑与表示混在同一个文件中。分开逻辑与表示使得当其中的任何一方需要改动是不至于影响到另外一方。JSP仅仅被作为前台的表示。那么,该如何实现商业逻辑部分呢?这就是JavaBeans的用武之地了。JavaBeans技术是轻便的、平台无关的组建模型,它使开发人员编写组件并且可以处处运行。在JSP环境中,JavaBeans组件处理商业逻辑并返回数据给JSP页面。JSP页面通过调用组件的get方法和set方法来操作Bean的各项属性。使用JavaBeans技术的好处如下:
1 可重用:不同的应用可以使用同一个组件。
2 分离逻辑与表示:你可以在JSP页面上改变数据的显示外观而不影响商业逻辑。换而言之,网页设计师只需要关注设计,Java开发人员只需要关注商业逻辑。
3 保护自己的知识产权。
如果你在你的项目中使用Enterprise JavaBeans(EJB)组件,商业逻辑必须保留在Ejb组件中,提供生命周期管理,事务支持与对多用户访问控制。关于这一点,你可以在Enterprise BluePrints中找到更为详细的资料。
l 使用自定义标记
l 不要重新发明轮子:对于普通的标记而言,JSTL中提供的标记以及足够。你尽可以使用。开发自定义标记意味着更多的测试与调试。
l 使用JSTL描述语言
l 如果可能,使用过滤器(filter):过滤器是JSP技术的新的特性。
l 使用轻便的隐私模型
l 为持久性信息使用数据库
l 缓存内容:
l 使用连接池
l 缓存数据库查询的结果:不要使用ResultSet来缓存数据,将ResultSet中的数据拷贝到Vector或RowSet
l 经可能采用新的JSP XML语法。
l 学习与应用Enterprise BluePrints