Servlet 和 JSP 技术是用 Java 开发服务器端应用的主要技术,是开发商务应用表示端的标准。 Java 开发者喜欢使用它有多种原因,其一是对于已经熟悉 Java 语言的开发者来说这个技术容易学习;其二是 Java 把“一次编写,到处运行”的理念带入到 Web 应用中,实现了“一次编写,到处实现”。而且更为重要的是,如果遵循一些良好的设计原则的话,就可以把表示和内容相分离,创造出高质量的、可以复用的、易于维护和修改的应用程序。
比方说,在 HTML 文档中如果嵌入过多的 Java 代码( scriptlet ),就会导致开发出来的应用非常复杂、难以阅读、不容易复用,而且对以后的维护和修改也会造成困难。事实上,在 CSDN 的 JSP/Servlet 论坛中,经常可以看到一些提问,代码很长,可以逻辑却不是很清晰,大量的 HTML 和 Java 代码混杂在一起,让人看得一头雾水。这就是随意开发的弊端。
如果你已经基本了解 JSP 和 Servlet 的各项技术(最好也开发过一些 Web 应用),那么我们可以一起探讨一下如何开发“好”的应用的一些指导原则。我们首先对 Servlet 和 JSP 技术做一个浏览。
· Servlet 和 JSP 概览
早期的动态网页主要采用 CGI ( Common Gateway Interface ,公共网关接口)技术,你可以使用不同的语言编写 CGI 程序,如 VB 、 C/C++ 或 Delphi 等。虽然 CGI 技术发展成熟且功能强大,但由于编程困难、效率低下、修改复杂等缺点,所以有逐渐被取代的趋势。在所有的新技术中, JSP/Servlet 具备更高效、更容易编程、功能更强、更安全和具有良好的可移植性,因而被许多人认为是未来最有发展前途的动态网站技术。
与 CGI 相似, Servlet 支持请求 / 响应模型。当一个客户向服务器递交一个请求时,服务器把请求送给 Servlet , Servlet 负责处理请求并生成响应,然后送给服务器,再由服务器发送给客户。与 CGI 不同的是, Servlet 没有生成新的进程,而是与 HTTP Server 处于同一进程中。它通过使用线程技术,减小了服务器的开销。 Servlet 处理请求的过程是这样的:当收到来自客户端的请求后,调用 service 方法,该方法中 Servlet 先判断到来的请求是什么类型的( GET/POST/HEAD… ),然后调用相应的处理方法( doGet/doPost/doHead… )并生成响应。
别看这么复杂,其实简单说来 Servlet 就是一个 Java 类。与一般类的不同之处是,这个类运行在一个 Servlet 容器内,可以提供 session 管理和对象生命周期管理。因而当你使用 Servlet 的时候,你可以得到 Java 平台的所有好处,包括安全性管理、使用 JDBC 访问数据库以及跨平台的能力。而且, Servlet 使用线程,因而可以开发出效率更高的 Web 应用。
· JavaServer Pages (JSP)JSP 技术是 J2EE 的一个关键技术,它在更高一级的层次上抽象 Servlet 。它可以让常规静态 HTML 与动态产生的内容相结合,看起来像一个 HTML 网页,却作为 Servlet 来运行。现在有许多商业应用服务器支持 JSP 技术,比如 BEA WebLogic 、 IBM WebSphere 、 JRun 等等。使用 JSP 比用 Servlet 更简单。如果你有一个支持 JSP 的 Web 服务器,并且有一个 JSP 文件,你可以把它放倒任何静态 HTML 文件可以放置的位置,不用编译,不用打包,也不用进行 ClassPath 的设置,就可以像访问普通网页那样访问它,服务器会自动帮你做好其他的工作。
· JSP 工作原理
JSP 文件看起来就像一个普通静态 HTML 文件,只不过里面包含了一些 Java 代码。它使用 .jsp 的后缀,用来告诉服务器这个文件需要特殊的处理。当我们访问一个 JSP 页面的时候,这个文件首先会被 JSP 引擎翻译为一个 Java 源文件,其实就是一个 Servlet ,并进行编译,然后像其他 Servlet 一样,由 Servlet 引擎来处理。 Servlet 引擎装载这个类,处理来自客户的请求,并把结果返回给客户,如下图所示:
图 1 : 调用 JSP 页面的流程
以后再有客户访问这个页面的时候,只要该文件没有发生过更改, JSP 引擎就直接调用已经装载的 Servlet 。如果已经做过修改的话,那就会再次执行以上过程,翻译、编译并装载。其实这就是所谓的“第一人惩罚”。因为首次访问的时候要执行一系列以上的过程,所以会耗费一些时间;以后的访问就不会这样了。
· 开发原则
这一部分我们列出一些开发原则,重点是 JSP 页面。关于如何分离表现和内容的 MVC 因为要涉及到 JSP 和 Servlet 的整合,我们稍候再谈。
- 不要在 JSP 页面中嵌入过量的 Java 代码: 对于非常简单或是测试性的代码,把所有的 Java 代码直接放入 JSP 页面内是没有问题的。但是这种方法不应该被过度使用,否则就会产生一大堆 HTML 和 Java 混合起来的代码,让人难以阅读和理解。解决方法是写一个单独的类,用来执行相关的计算。一旦这个类测试通过,就可以把它放在任何执行同样计算的场合中。这样可以促进代码的复用。
- 选择合适的包含( include )机制 : 如果一个应用中每个页面有一样的抬头和底部,或者还有导航条,那么就应该把它们放到一个单独的文件中,然后在每一个页面中使用包含机制把它们加入到这个页面中:
- Include 指令: <%@ include file="filename" %> 或等效 xml 语法
<jsp:directive.includefile=”filename” />
- Include 动作: <jsp:include page="page.jsp" flush="true" />
Include 指令是当 JSP 页面翻译为 Servlet 的时候包含另外一个文件, Include 动作是当请求时包含另外一个文件的输出。如果被包含的文件不是经常改动的时候,我建议使用 Include 指令,这样速度更快。如果被包含的文件需要不时改动或者知道请求时才能决定需要包含的内容时,那么应该使用 Include 动作。
如果你使用 JSP 标准标记库( JavaServer pages Standard Tag Library 即 JSTL )的话,那么还有第三中包含机制 <c:import> ,可以用来包含本地或者远程的资源。例如:
<c:import url="./copyright.html"/>
<c:import url="http://www.somewhere.com/hello.xml"/>
- 不要把业务逻辑和表示混合在一起: 复杂的应用涉及大量的代码,因而把业务逻辑和前端的表示相分离就显得格外重要,这种分离可以让任何一方的变化不会影响到另外一方。所以,所有的 JSP 代码都应该限制在表示层,可是如果这样的话,你如何实现你的业务逻辑呢?这就是 JavaBean 所做的事情。 JavaBean 技术是一个独立于平台的组件模型,它让开发者编写、测试通过一个组件后,可以随处使用,提高了复用性。在 JSP 技术中, JavaBean 实现了业务逻辑部分,它把数据返回给 JSP 页面,由 JSP 页面负责格式化数据并输出到客户端的浏览器。在 JSP 页面中使用 JavaBean 组件的好处是:
- 产生了可以复用的组件:任何应用都可以使用这些组件
- 可以把业务逻辑和表示相分离:你可以修改数据的显示方式而不用考虑业务逻辑。这样做的结果也可以明确工作中开发人员的分工,网页开发人员可以把精力放到如何显示数据上, Java 开发者则更为关注业务逻辑的实现。
- 对于 JavaBean 你不用提供源代码,这样你的代码就不会被浏览器网页的人轻易获得,可以保护你的劳动成果。
如果你的应用中使用了 EJB 组件,那么业务逻辑就应该放置在 EJB 中,因为 EJB 模型提供了生命周期管理、事务管理以及多客户访问域对象( Entity Beans )。你可以仔细看一下 Enterprise BluePrints 中的例子,它就是这么做的。
- 使用定制的标记: 上面我们已经讨论过,把所有 Java 代码嵌入到 JSP 页面内并不合适,因为网页开发人员并不一定懂得 Java 语言,更难以理解 Java 语法。 JavaBean 可以封装很多 Java 代码,不过在 JSP 页面内使用 JavaBean 仍然要求页面开发人员了解一些 Java 语法。
JSP 技术中包含了定制标记库的功能。 Java 开发人员可以生成自己的标记库,这样网页设计人员就可以使用类似 HTML 的语法来使用这些标记。编写和使用自己定制的标记库可以在更大程度上促进业务逻辑和表示的分离。使用定制标记库主要有以下好处:- 可以消除在 JSP 页面中使用 scriptlet 。标记使用的任何参数都可以通过属性传入,从而不需要使用 Java 代码就可以达到希望的目的。
- 可以简化使用。网页设计人员不需要学会使用 Java 语法,他们可以用类似 HTML 语法就可以使用标记。
- 不懂 Java 的网页设计人员可以使用标记库来完成单独使用 HTML 不能完成的任务。
- 提高了复用性。标记库完全可以复用,这可以节省开发和测试的时间。 Scriptlet 代码只能在“拷贝粘贴”级别上进行“复用”。
简单说来,你可以像用 HTML 构建表示层一样使用标记库完成非常复杂的任务。下面是表页标记库的一些注意事项:
1. 保持简洁性:如果一个标记需要好几个属性的话,那么尽可能把它分为几个标记。
2. 保持复用性:同标记的使用人员(网页设计人员)多多交流,尽量开发出可以高度复用的标记库。
3. 不要一切都从头开始:现在已经有一些可以免费使用的标记库,比如 Jakarta Taglibs 。如果你要用到一个标记,先看看是不是已经有现成的可以使用。








