Servlets和JSP开发原则探讨

 
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因为要涉及到JSPServlet的整合,我们稍候再谈。

  • 不要在JSP页面中嵌入过量的Java代码:对于非常简单或是测试性的代码,把所有的Java 代码直接放入JSP页面内是没有问题的。但是这种方法不应该被过度使用,否则就会产生一大堆HTMLJava混合起来的代码,让人难以阅读和理解。解决方法是写一个单独的类,用来执行相关的计算。一旦这个类测试通过,就可以把它放在任何执行同样计算的场合中。这样可以促进代码的复用。
  • 选择合适的包含(include)机制:如果一个应用中每个页面有一样的抬头和底部,或者还有导航条,那么就应该把它们放到一个单独的文件中,然后在每一个页面中使用包含机制把它们加入到这个页面中:

    1. Include 指令: 或等效xml语法

                    

    1. Include 动作:


Include
指令是当JSP页面翻译为Servlet的时候包含另外一个文件,Include 动作是当请求时包含另外一个文件的输出。如果被包含的文件不是经常改动的时候,我建议使用Include 指令,这样速度更快。如果被包含的文件需要不时改动或者知道请求时才能决定需要包含的内容时,那么应该使用Include 动作。

如果你使用JSP标准标记库(JavaServer pages Standard Tag LibraryJSTL)的话,那么还有第三中包含机制,可以用来包含本地或者远程的资源。例如:

  1. 不要把业务逻辑和表示混合在一起:复杂的应用涉及大量的代码,因而把业务逻辑和前端的表示相分离就显得格外重要,这种分离可以让任何一方的变化不会影响到另外一方。所以,所有的JSP代码都应该限制在表示层,可是如果这样的话,你如何实现你的业务逻辑呢?这就是JavaBean所做的事情。JavaBean技术是一个独立于平台的组件模型,它让开发者编写、测试通过一个组件后,可以随处使用,提高了复用性。在JSP技术中,JavaBean实现了业务逻辑部分,它把数据返回给JSP页面,由JSP页面负责格式化数据并输出到客户端的浏览器。在JSP页面中使用JavaBean组件的好处是:

     

    1. 产生了可以复用的组件:任何应用都可以使用这些组件
    2. 可以把业务逻辑和表示相分离:你可以修改数据的显示方式而不用考虑业务逻辑。这样做的结果也可以明确工作中开发人员的分工,网页开发人员可以把精力放到如何显示数据上,Java开发者则更为关注业务逻辑的实现。
  • 不要“重新发明轮子”,不要一切从头开始:通过定制组件可以提高复用性,不过定制组件仍然需要编写、测试和调试程序。问题是这个事情别人可能已经实现了,而且你的实现方式并不一定比人家做得更好。这就是JSP标准标记库(JavaServer Pages Standard Tag Library, JSTL)要做的事情(JSTL请参考JSTL官方网站)。JSTL提供了循环、读属性、遍历各种数据结构、条件表达式求值等各种标记。它也提供了一些复杂的标记,甚至像解析XML文档的标记它都有。所以如果你要用到一个标记的话,最好先看看有没有别人已经实现的可以使用,而不要次次从头开始,自己搞一套。
  • 使用JSTL表达使语言(JSTL Expression Language):传递给JSP页面的数据一般通过JSP作用域属性或者请求参数来进行。专门为网页开发者设计的表达式语言(Expression Language, EL)把使用作用域属性传递信息作为从业务逻辑向JSP页面传递信息的标准方式。这里要注意的是,EL只是JSP技术中关键的一个方面,并不是一种通用的程序设计语言。相反,它只是一种数据访问语言,它可以简化应用程序的数据的访问,不用Scriptlet和请求时表达式求值就可以访问数据。

    JSP中,网页设计师要使用表达式语法 JavaBean组件来取得某些变量或属性的值,例如:
    
         pageContext.getAttribute("name") %>">

 

 

 

 

 

表达使语言让网页设计师可以使用简化的语法来访问信息。如果你只是要访问一个简单的变量,你可以使用这样的语法:

 

 

 

如果你要访问一个嵌套 JavaBean 的属性,你可以这样:

 

     aCustomerBean.address.country}">

 

 

表达式语言(EL)借用了JavaScript 的语法,所以如果你对JavaScript 很熟悉的话,你就会觉得巨爽。

  • 使用过滤器(filter):过滤器是一个对象,可以传输请求或修改响应。它可以在请求到达Servlet/JSP之前对其进行预处理,而且能够在响应离开Servlet/JSP之后对其进行后处理。所以如果你有几个Servlet/JSP需要执行同样的数据转换或页面处理的话,你就可以写一个过滤器类,然后在部署描述文件(web.xml)中把该过滤器与对应的Servlet/JSP联系起来。

创建过滤器其实很容易,你只须实现javax.servlet.Filter接口及它的三个方法:

public void init(FilterConfig config)

public void doFilter(ServletRequest req, ServletResponse rep,

FilterChain chain)

public void destroy()

这样,你就可以完成你的过滤器。

  • 使用可移植的安全模型:大部分的应用服务器都提供了安全模型,不过一般它们都是针对某一个服务器或某一个厂商专有的。如果你的应用需要移植的话,那么你的应用最好使用可以移植的安全模型。如果你的应用有一些预先定义的固定用户的话,那么你可以使用FROM验证和BASIC验证。可是如果你要动态生成客户的话(一般都是这种情况),你可能就需要使用服务器特定的API来创建和管理用户。这样当你的应用移植到另外一个服务器时,你可能就会碰到API不兼容的问题。这种情况下,最好的解决方法是使用适配器(Adapter)模式(如果你对设计模式不熟悉的话,请参看GoF的《设计模式》一书)。
  • 用数据库来保存持久性数据: Servlet/JSP中可以使用HttpSession对象也就是会话对象来保存用户的临时数据。不过如果你想保存持久性数据的时候,你应该使用数据库,数据保存数据会更安全,而且对客户所用的浏览器没有什么要求。这样即使你的应用服务器由于某种原因崩溃了,你的数据依然良好。
  • 高速缓存页面:应用程序中总有一些东西是相对固定的,而另外一些东西是经常变化的。你应该使用静态的HTML文档来存储那些相对固定的内容,这样客户端就可以进行高速缓存,客户每次访问你的应用时,只需访问已经改动的部分。这样可以加快客户的访问速度。
  • 使用连接池:如果你要自己写数据库访问代码的话,我觉得使用你应该学会如何使用数据库连接池技术。每一个服务器都有针对数据库连接池的配置文档,你要学习一下如何使用。数据库连接池可以加速你的应用的数据访问的速度,而且由于服务器替你管理了数据库连接,这可以节省你的很多工作。
  • 缓存数据库的访问结果:如果你的应用要对数据库进行频繁访问的话,你可以使用一个对象来缓存你的数据,这样你就可以节省大量访问数据库的开销。在《J2EE核心模式》和《实用J2EE设计模式编程指南》两本书中都有关于值对象模式(Value Object Pattern)的详细探讨,你可以参考这两本书来获得相应的知识。
  • 使用数据访问对象模式:如果你的应用需要访问多个数据库系统或者可能会移植到其它的存储系统中,那么你针对特定厂商的优化代码就可能会失效。使用通用的代码存在执行效率的问题,而使用优化代码又存在移植的问题。所以就产生了数据访问对象模式(Data Access Object Pattern, DAO),该模式既提供了各数据库厂商的适应性,又能利用到他们提供的独特的好处。按照面向对象的分离任务的原则,该模式将与企业信息系统(Enterprise Information System, EIS)通讯需要的逻辑隔离到它自己的类中。这样,事物对象,如Servlet/JSP组件、JavaBean就可以利用数据访问对象(DAO)处理所有与EIS有关的事务。
  • 最好采用JSPXML语法: JSP技术中经常存在着两种完成同一个任务的语法,一种是常规的JSP语法,一种是对应的XML语法。虽然两种语法作用相同,你最好还是使用XML语法。存在两种语法的原因是,JSP语法可以与以前的代码兼容,而J2EE使用XML作为其交换数据的核心,所以同时提供了XML语法。随着J2EE的发展,XML的作用会越来越大,所以我建议你使用XML语法。
  • 研究Sun提供的J2EE BluePrints: SunEnterprise BluePrints 提供了大量指导原则、设计模式和很好的例子(宠物店,Pet Store)。你可以好好研究一下这些内容,这样可以提高你的设计和开发水平。

整合 Servlet JSP

 

JSP 技术规范种给出了两种使用 JSP 开发 Web 应用的方式,这两种方式可以归纳为模型一和模型二,这两种模型的主要差别在于它们处理业务的流程不同。模型一,如下图所示,称之为 JSP+JavaBeans 模型。在这一模型中, JSP 页面独自响应请求并将处理结果返回给客户,所有的数据通过 JavaBean 来处理, JSP 实现页面的表现。
 


2 JSP 模型一
 

 

从上图可以看出,模型一也实现了页面表现和业务逻辑相分离。然而使用这种方式就要在 JSP 页面使用大量的 Java 代码,当需要处理的业务逻辑很复杂时,这种情况会变得非常糟糕。大量嵌入式代码使整个页面程序变得异常复杂。对于前端界面设计的网页开发人员来说,这简直是一场噩梦。所以,模型一不能满足大型应用的需要,但是对于小型应用,因为该模型简单,不用涉及诸多要素,从而可以很好地满足小型应用的需要,所以在简单应用中,可以考虑模型一。

 

模型二,如下图所示,称之为 JSP+Servlet+JavaBeans 模型。这一模型结合了 JSP Servlet 技术,充分利用了 JSP Servlet 两种技术原有的优势。这个模型使用 JSP 技术来表现页面,使用 Servlet 技术完成大量的事务处理,使用 Bean 来存储数据。 Servlet 用来处理请求的事务,充当一个控制者的角色,并负责向客户发送请求。它创建 JSP 需要的 Bean 和对象,然后根据用户请求的行为,决定将哪个 JSP 页面发送给客户。
 


3 JSP 模型二
 

 

从开发的观点看,模型二具有更清晰的页面表现,清楚的开发角色的划分,可以充分利用开发团队中的网页设计人员和 Java 开发人员。这些优势在大型项目中表现得尤为突出,网页设计人员可以充分发挥自己的美术和设计才能来充分表现页面,程序编写人员可以充分发挥自己的业务逻辑处理思维,实现项目中的业务处理。

 

另外,从设计结构来看,这种模型充分体现了模型视图控制器( MVC )的设计架构。事实上,现存的很多开发框架都是基于这种模型的,充分实现了 MVC ,例如 Apache Struts 框架和 JavaServer Faces 框架(关于 JavaServer Faces 框架,我翻译了一篇介绍性的文章 用JavaServer Faces开发Web应用 》,大家可以参考一下;关于 Struts ,大家可以参考 Apache网站 )。

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值