1.1 JSP的概念和作用

按照脚本语言是服务于某一个子系统的语言这种论述,JSP应当被看做是一种脚本语言。然而作为一种脚本语言,JSP又显得过于强大,因为在其中几乎可以使用全部的Java类。

本节我们将介绍JSP的基础知识及学习建议。

1.1.1 什么是JSP

简要地说,JSP是用来开发含有动态内容网页的一种技术。纯HTML网页只会包含静态的内容,即其内容通常保持不变。而JSP页面则不同,它可以根据任意数量的变量来动态调整自己页面中的内容,这些变量可以是身份验证信息、用户提供的对象信息、页面颜色,还可以是用户所做的一切选择等。这些功能对于创建像淘宝网这类在线购物及旅店、机票预订,以及对内容进行多国语言的国际化和个性化的Web应用程序来说是非常关键的。

JSP虽然功能强大,但其页面和常规的HTML网页一样,也包含标准的标记语言元素,如HTML的标签。同时,JSP页面还包括自身特殊的JSP元素,这些元素将允许服务器把动态内容添加到页面上。JSP自己的元素用途非常广泛,它可以读取数据库的数据信息,以及记录用户需要保存的信息等。

现在我们来看一个简单的JSP页面执行过程。当用户请求一个JSP页面时,JSP执行过程如图1-1所示。

图1-1 JSP的执行过程

(1)客户端发出Request(请求)。

(2)JSP容器(服务器)将JSP转译成Servlet的源代码。

(3)将产生的Servlet的源代码经过编译,并加载到内存执行。

(4)把结果Response(响应)至客户端。

JSP除定义了自身特殊的元素外,还定义了许多用于Web应用程序的标准元素,如引用JavaBeans的元素及共享信息的元素。开发人员也可以通过使用应用程序的专用元素来扩展JSP语法,从而完成诸如访问数据库和EJB、发送电子邮件,以及生成表示应用程序专用数据的HTML这样的任务。JSTL规范(与JSP规范相关的一种规范)也定义了一组这种常用的自定义元素,标准元素和自定义元素的组合可以让开发人员开发出强大的Web应用程序。

1.1.2 JSP和Servlet扮演的角色

Sun公司首先发展出Servlet,其功能强大且体系设计很完善。但其输出HTML语法时必须使用out.println()逐句输出,如下面一段简单的程序所示:

      out.println("<html>");
      out.println("<head><title>First Servlet</title></head>");
      out.println(" Hello World <br>");
      out.println("<body>");
      out.println("您好");
      out.println("</body>");
      out.println("</html>")

由于这是一段简单的Hello World程序,还看不出其复杂性。但是当整个网页内容非常复杂时,Servlet程序可能大部分都是用out.println()输出HTML的标签了!

后来Sun公司推出类似于ASP的嵌入型脚本语言并且命名为“JavaServer Pages”,简称为“JSP”,于是上面那段程序改为:

      <html>
      <head><title>www.csdn.cn –中国软件开发网 </title></head>
      <body>
      <%
        out.println(" Hello World <br>");
        out.println("您好");
      %>
      </body>
      </html>

虽然表面上JSP代替了Servlet完成了请求响应,但实际上JSP仍然需要结合Servlet技术才能完成自己的任务。因为JSP页面在Web服务器端执行时首先转译成Servlet类,然后通过执行转译后的Servlet把响应结果送到客户端,读者可参考图1-1。

可以说JSP注重于Web应用程序的前端视图,而Servlet则注重于Web应用程序的逻辑控制。现在大多数Web应用程序把这两种强大的技术结合起来,因为二者的结合是一个强大的工具,使用这种工具可以开发出易于维护且能够随着新的需求进行扩展的伸缩性强的应用程序。由于Servlet是一个普通的Java类,因此可以借用Java语言的全部能力,通过标准的Java开发和调试环境来实现请求处理。然后可以把JSP页面用在最适合它的地方,如前端视图中,使用Servlet收集或生成的信息把应答通过JSP显示。

自从JSP技术产生以来,将其与Servlet结合起来的Web开发框架有很多,如JSP+Servlet+JavaBeans模式、基于JSP和Servlet的MVC(Model View Control,模型视图控制器)模式等。这些典型的框架技术目前都很受开发人员的青睐,在后面的章节中我们将会详细介绍。

1.1.3 JSP和其他框架的集成

JSP作为J2EE的一部分,既可以用于开发小型的Web站点,也可以用于开发大型企业级的应用程序。

对于最小型的Web站点,可以直接使用JSP来构建动态网页。这种站点最为简单,所需要的仅仅是简单的留言板及动态日期等基本的功能。对于这种开发模式,一般可以将所有的动态处理部分都放置在JSP的Scriptlet中,就像使用PHP或ASP开发动态网页一样。

中型站点面对的是数据库查询、用户管理和小量的商业业务逻辑,在这种站点中,不能将所有的内容全部交给JSP页面来处理。在单纯的JSP中加入Java Beans技术将有助于这种中型网站的开发。利用Java Beans将很容易完成如数据库连接、用户登录与注销及商业业务逻辑封装的任务。例如,将常用的数据库连接写为一个Java Beans,既方便了使用,又可以使JSP文件简单而清晰,通过封装还可以防止一般的开发人员直接获得数据库的控制权。

然而对于大中型网站来说,最复杂的就是如何把业务、逻辑控制和视图这几个方面完全清晰地区分开来,而不是由传统的JSP+Java Beans方式来实现。因为那样会让商业逻辑、数据库及视图控制方面很混乱,不易维护及扩展,并且可伸缩性差。这样就产生了用于区别商业逻辑、业务及视图控制的技术及其开发框架,典型的有EJB、Struts、Hibernate及Spring等框架技术。下面我们简单来看几个典型JSP和其他技术及框架相集成的技术。

(1)JSP+Java Beans+DataBase。

这个模型主要的特点就是JSP全权接收请求并发送响应,而Java Beans的作用是和数据库服务器进行通信,读取数据。然后将数据信息发送至JSP页面,如图1-2所示。

图1-2 JSP+JavaBean的框架实现

(2)JSP+JavaBeans+Servlet+DAO。

该模型集成使用了Servlets和JSP页面,如图1-3所示。其中JSP页面用于表示层,并且Servlets负责处理各类任务。Servlet作为一个控制器,负责处理请求并创建JSP页面所需的任何Bean,并确定将该请求传递到哪个JSP页面。JSP页面检索Servlet创建的对象,并提取动态内容插入在一个模板中。

图1-3 JSP+Servlet+JavaBean的MVC框架实现

该模型促进了MVC体系结构风格设计模式的使用,早就存在多个框架能够实现MVC这个有用的设计模式,并将内容和表示真正地分离开来。Apache Struts是MVC的形式化框架,非常适用于复杂的应用程序。在这些复杂的应用程序中,单个请求或表单提交会产生看起来截然不同的结果。

(3)JSP+Serlvet+EJB。

EJB(Enterprise JavaBeans)带给我们的是一种基本的事务管理和一种与客户端类型无关的组件模型,它加强了对模型(Model)、视图(View)和控制器(Controller)的划分,从而使整个应用程序更易于扩展和维护。

EJB组件有两种基本类型,即实体Bean和会话Bean。实体Bean表示的是特定的一部分商业数据,例如,一个员工或一个客户的数据。每个实体Bean都有一个唯一的标识符,要访问这个实体的所有客户都将使用同一个Bean实例;而会话Bean主要用来处理商业逻辑,而且只能由创建它的那个客户使用。通常,会话Bean代表其客户操作实体Bean。

在一个EJB应用程序的Web界面中,请求被发送给一个Servlet,这与JSP+Servlet方案一样。该Servlet将不再处理这个请求,而是请求一个EJB会话Bean(或者一个用到EJB会话Bean接口的Web层组件)来完成对请求的处理。因此控制器角色跨越了Servlet和EJB会话Bean,模型也可以跨越多个组件。通常我们使用Web层之间的通信,当完成对请求的处理后会话Bean可能更新了许多EJB实体Bean。这时,Web层中的Java Beans组件将会接到通知,从而自动地更新其状态。随后一个JSP页面将使用这些组件来生成一个应答,这样模型角色由EJB实体Bean和Web层中的Java Beans组件共同承担。

基于EJB的应用程序通常被看做是无所不能的,然而它是最复杂的模型,因此需要在开发、配置、操作和管理领域多做许多事情。尽管EJB可能是一种开发某种类型应用程序的比较好的方式,但它对许多人来说过于复杂了。因此在决定使用EJB之前,应仔细考虑到底是否真的需要EJB。

(4)JSP+Struts+JavaBeans+DAO。

JSP和Struts框架的集成实际上就是MVC框架(如图1-3所示)技术的延展,可用于快速开发Java Web应用。Struts实现的重点在控制器,包括ActionServlet/RequestProcessor,我们定制的Action也为视图提供了一系列定制标签(Custom Tag)。但Struts几乎没有涉及模型,所以它可以采用JAVA实现的任何形式的商业逻辑。

Struts本身负责将MVC中的用户数据传入业务层,并且将业务层处理的结果返回给用户。

(5)JSP+Struts+Hibernate。

Hibernate是一个面向Java环境的对象/关系数据库映射工具,这种映射工具用来把对象模型表示的对象映射到基本SQL的关系模型数据结构中。

Hibernate使用数据库和配置文件来为应用程序提供持久化服务,如图1-4所示为其概览。

图1-4 Hibernate概览

Hibernate不仅仅管理Java类到数据库表的映射(包括Java数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。

Hibernate的目标是对于开发人员通常持久化相关的编程任务减轻其中任务量的95%,对于那些在基于Java的中间层应用中实现面向对象的业务模型和商业逻辑的应用,它很有用。

在没有Hibernate之前,我们通过Java Beans或DAO来实现数据库底层的数据通信,其开发任务大,且责任重大。也可能是修改最频繁的模块,并且不利于扩展和修改,兼容性差。通过JSP+Struts+Hibernate的集成,数据处理模块大大减轻了负担。这样视图层专门由JSP来完成,Struts实现的重点是控制器的角色,它负责从Hibernate中读取数据信息并传送给JSP来显示。而Hibernate专门负责模型与数据库的通信,定制数据库映射对象及HSQL语句来完成数据库表的映射、查询及获取数据等关键任务。

(6)JSP+Struts+Hibernate+Spring。

Spring是一个服务于所有层面的应用程序框架,提供了Java Bean的配置基础、AOP的支持、JDBC的提取框架,以及抽象事务支持等。

相对于EJB来说,Spring是一个轻量级的J2EE应用开发框架。这里提到的轻量级指的是Spring框架本身,而不是说Spring只能适用于轻量级的应用开发。其轻量级体现在框架本身的基础结构,以及对其他应用工具的支持和装配能力。与EJB这种庞然大物相比,Spring使我们降低了各个技术层次之间的风险。EJB的内聚性较强,比如数据持久层管理、事务管理及生命周期管理都全部交给容器管理,内聚性的白盒特征使我们必须放弃一部分可控性而信任容器能力。而Spring则是考虑如何“不造轮子”,即更好地组装这些轮子,让它们更好地转动。例如,数据持久层管理可以使用Hibernate,日志管理可以使用jakarta.common.logging。

Spring的主要部分为Bean+ApplicationContext,它以一种统一的Ioc方式查找、管理、组装并使用系统的组件取代一切工厂,包括持久化框架,及Web框架等。

JSP+Struts+Hibernate+Spring目前被J2EE开发行业内视为J2EE框架的最佳组合,其结构如图1-5所示。在这个组合中,表示层由Struts来实现,业务逻辑类可以用Spring的beans进行配置,并由Spring管理与表现层的控制器及更下层的DAO对象的关系。另外,还可以进行配置性的事务处理。而DAO层是Spring封装后的Hibernate API,让Hibernate继续瘦身,并且通过Spring建立与上层的关系。

图1-5 使用Struts及Hibernate的Spring中间层

1.1.4 学习JSP网站编程

如何学习JSP编程,以成为一个成功的JSP开发人员?一个常见的误解是把JSP当做简化的Java,开发人员通常试着没有学习要求的支持技巧而直接学习JSP。JSP是一个衔接技术,并且要成功地衔接开发人员需要理解的另外的技术。如Java、HTML和JavaScript,这是学习JSP之前最好能掌握的。

笔者的建议如下。

(1)架设Web Server,并理解它。

因为Apache是免费的且在大多数平台上工作,所以为训练目的,推荐Apache。

(2)学习和理解HTML。

务必要了解HTML基础,特别是HTML布局中如table及body等这些重要标记的使用方法。许多开发人员通过HTML IDE学习HTML。因为大多数HTML IDE产生混乱的TMl语法,所以花时间学习手工编写HTML是很有必要的,使用JSP和HTML混合编程精通HTML语法是重要的。

(3)学习Java语言编程基础。

必须认真学习Java,因为它是一门全新的面向对象编程语言,和C、C++并列为3大开发语言。并且JSP和Servlet都是以Java语言为基础的,因此Java基础很重要。如果有面向对象编程语言(如C++)经验,那么学习Java将会很快。不用担心学习Swing或Java的图形方面,因为在JSP中不会使用这些特征。集中精力 在Java工作的细节,学习Java的逻辑及面向对象的编程思想,也要在Java Bean上花时间。学习Applet是好的,但是如Swing及JSP之类的大多数应用将不使用小程序。

在这方面的书籍很多,典型的有《Thinkin in Java》(第三版)及《Java2核心技术》等。

(4)学习JavaScript。

JavaScript是网页编程中一种高效的脚本语言,用其可以减轻编写JSP页面中一些重要功能的负担。应该学习如何用JavaScript在HTML中验证输入的Form元素,也要学习JavaScript如何能在一页HTML以内修改Form的元素。还要学习如何编写JavaScript函数,最后要求能从一页HTML内的事件中触发JavaScript函数。

(5)建立JSP Server并理解其结构及内部运行机制。

典型的JSP Server包括Tomcat、Jboss、WebLogic及Websphere等,推荐从Tomcat 5.5开始。它相比其他服务器小型且灵活,可以很好地运行JSP程序。另外,许多JSP开发人员使用Tomcat,因此当遇到一个问题时将容易得到帮助。

(6)开始学习JSP。

掌握了Java、JavaScript及HTML的知识后,可以开始完全以本书作为教程来学习JSP。

除了本书以外,如果要在某一方面了解更详细的内容,可以参考专项的书籍。如在Servlet方面有Dustin R.Callaway著的《精通Servlets》、Struts方面有Ted Husted著的《Struts In Action》、Hibernate方面有《Hibernate——符合Java习惯的关系数据库持久化》,以及Spring方面的《Spring 2.0 FrameWork中文参考手册》等。

(7)学习更多的JSP Server。

其他更多的JSP Server当然也可以运行JSP程序,然而许多JSP Server都由自己特殊的特征,可以让你更好地理解JSP工程。例如,Jboss是开源且免费的,如果想了解J2EE服务器内部机制,就可以学习并理解其源代码。也可以在它的基础上进行二次开发及封装,让其变成自己开发的Web服务器。而Weblogic和WebSphere这种大型服务器软件的特点是稳定且吞吐量巨大,对于架设数据海量且需要稳定的Web应用程序来说是很不错的,但它们也是昂贵的。

(8)学习敏捷开发、设计模式及J2EE体系架构等方面的知识。

良好的软件不仅在于其功能完备、易用性强,更在于其扩展性好且可伸缩性强,达到这种要求的软件就需要有好的架构及设计思想,而敏捷开发及设计模式等就是教导开发人员如何实现伸缩性强的代码和设计。而J2EE体系架构方面的学习将会让你对整个Web应用程序的框架设计有一种像建筑师一样的设计及规划理念。