概要:
随着JSP规范的不断进展,以及可用的jsp开发工具数量不断增多,以及jsp技术可涉及领域的不断的扩展,促进了基于 jsp技术的高维护性能和标准化的网络应用的开发。这篇文章讨论了在jsp进展的一些主要的内容以及这些是如何更加容易的开发处健壮的JSP网络应用。
这篇文章的最佳实践将能够帮助应用JSP强大的功能以及能够让你为将来JSP的升级做好准备。
JSP规范支持JSP pages同样也支持JSP
document.。两者之间主要的区别是它们对XML兼容的程度。JSP pages使用传统的或者说是“速记(shorthand)”语法,而JSP document.用的语法完全与XML相兼容。JSP document.时候被成为是使用了XML语法的JSP pages。但是这里我将分别称它们为JSP pages和JSP document.便加以区分。
基于以下几个原因我推荐使用JSP document.
JSP document.很好组织了的XML\HTML(You can easily
verify JSP document. as
well-formed XML/HTML)
可以使用XML Schema来验证JSP document.
l 可以很容易的使用标准的XML工具来写和解析
可以使用XSLT(Extensible Stylesheet Language Transformations)以不同的form来编写JSP document.具体请看“JSP
document.nbspwith XSLT”
http://www.javaworld.com/javaworld/jw-07-2003/jw-0725-morejsp.html?#sidebar1 需要什么来搜一搜吧so.bitsCN.com
JSP使用了XML相容include和forward action,custom标签,因而使得整个document.XML相容,这样就提高了编码的一致性。
JSP document.相对JSP pages需要稍微多一点的开发规则,但是带来的好处是更加容易阅读和维持的document.,特别是对于刚刚开始学习JSP的人来说。
关于创建JSP document.和其特点的详细内容请参考“Write JSPs in XML
Using JSP1.2”(http://www.javaworld.com/javaworld/jw-07-2003/jw-0725-
morejsp.html?#resources)
JSP document.最大的缺点是没有与XML相兼容的JSP注释存在。JSP document.以使用客户端的注释(HTML-/XML –style)或者是嵌入的java注释。但是没有JSP document.<%-- --> 而JSP可用的上面的两种注释方法都有其自身的缺点。你可以在得到的网页中看到客户端的注释(通过浏览器视图里面的“查看源文件”功能),而且要使用 java的注释需要将java代码直接的写在JSP document.中。
在本文剩下的章节中,我将使用JSPs来代表JSP pages和JSP document.,因为我所讨论的最佳实践同样的适用这两种形式的JSP。
使用JSP的编码规范
无论使用任何一种语言,创建的任何工程,在提高开发,维护,和测试你的软件的角度遵循编码的标准和规范都是很明智的选择。读其他开发人员的代码并不简单 而且也不是愉快的事情。但是,如果所有的开发人员都遵循同样的命名规范和其他的一些约定的化,阅读代码和维护就会使得阅读代码对他人和编程人员自己变的容 易一些。 bbs.bitsCN.com国内最早的网管论坛
Sun Microsytem 最近已经帮助一些组织来创建这样的规范,制定了文档“Code
Conventions for the JavaServer Pages Technology Version 1.x Language”可以免费获得,参考“Resources”(http://www.javaworld.com/javaworld/jw-07-
2003/jw-0725-morejsp.html?#resources)。如果你的公司还没有遵循JSP编程规范的话,我建议使用这个文档作为一个起点。你可以完全的遵照该文档也可以在其基础上创建自己的规范。
为对象选择合适的Scope
JSP 规范支持四种scope(应用application,会话session,请求request和页面page),在JSPs中你可以为创建的对象选择其 中的一种,因为绑定到这些scope的对象消耗内存,并且在有些时候需要释放,所以最好选择适当的scope来完成你的任务。
应用范围(Application
scope)
Application scope 是最为广泛的一个范围,应该在必要的时候才采用这种形式。你可以在非会话相关(session-aware)的JSPs中创建绑定到 application的对象(You
can create objects bound at application level in JSPs that are not
session-aware,)在这种类型的JSPs中可以用应用范围来存储数据和信息。( so
application scope is useful for storing information when using these types of
JSPs)。你也可以使用绑定到application的对象用来在不同的会话(session)间共享数据。当你不需要application范围的对 象的时候一定要显式的删除它们以便释放内存。 bitsCN_com关注网管是我们的使命
会话范围(session scope)
在我的经验中,会话范围要比应用范围用的多。会话范围允许你创建并且将对象绑定到一个会话上面。你必须在session-aware的JSPs中创建绑 定在会话的对象并且使在同一个会话中所有的JSP和servlet能够访问到这些对象。会话范围常常用在管理安全验证和管理多个页面的状态信息。绑定在会 话范围的对象在不需要的时候也要显示的删除。当我计划将某个类的对象绑定到会话范围的时候我通常会使该类可串行化。
请求范围(request scope)
在绑定对象的时候,页面范围我用的最多。此类对象只在同一个请求的页面间有效。在请求处理完成的时候这些对象将会自动的被释放。因而不需要显式的释放它们,这样就没有了使系统被一些不必要内存消耗而拖累的危险。
页面范围(page scope)
当你创建只对当前页面相关的对象的时候你需要选择页面范围。和请求范围一样,绑定在页面范围的对象不要显式的删除。我很少在我的JSP应用中使用“页面范围”,但是这是<jsp:useBean>的默认范围。
选择哪种范围(scope)
需要仔细的选择创建对象的范围来保证有效的利用内存,通常我会在刚刚开始的时候选择请求范围,然后在评估是否需要选择范围更大的范围。 bbs.bitsCN.com国内最早的网管论坛
仔细的管理会话范围
前面已经提到过,只有在必要的时候才选择会话范围并且当这些对象不在需要会话级访问的时候需要显式的去掉对象的其会话范围。当不使用会话范围的对象的
JSP中你可以设置页面的directive的session属性为false,这样可以避免管理会话范围。但是,很少的网络应用不需要会话范围的支持。 通常,我使用会话来支持安全机制以及其他的一些应用需求。尽管一个会在一个可以由你配置的时间后过期,但是在不需要对象的会话范围的时候最好显式的取消它 们,而不是依赖会话自动释放的功能。
采用JSTL(标准标签库)
JSP的引入和采纳已经成为JSP开发人员的一个最为重要的进步。JSTL有时候也称为“JSP Standard Tag
Library”。在JSTL中的T代表的是标签(Tag)而不是模板(Template)。
JSTL:背景与回顾
在我以前的文章里,我提到过JSP开发人员采纳可以得到的自定义标签库而不是自己从头开始创建。有许多的商业的或者开源的自定义标签库现在已经可以加以 利用。但是有一个缺点就是:开发人员需要在JSP中按照这些自定义标签库所特定的格式来应用这些标签。JSTL的出现解决了这个问题,因为JSTL提供了 自定义标签的标准接口,这些标签足以满足JSP开发人员的一些基本的要求。(The advent of
JSTL has addressed this downside by providing standard interfaces to the custom
tags that perform many basic functions JSP developers need.) 不同的供应商可能以不同的形式实现这些JSTL标签,但是JSP开发人员不要知道实现标签时的不同点。如果JSP开发人员使用JSTL编写了JSP page或者JSP
document.JSP page或者JSP document.该适用所有的JSTL实现方法。 需要什么来搜一搜吧so.bitsCN.com
有许多有价值的书和一些在线的资源可以去学习JSTL。这里我将主要简单的介绍JSTL的优点与特性。
JSTL的优点
简短的说,JSTL提供了所有的已经公布的自定义标签库所有的好处,而且提供标准化的标签API。JSTL促进了高可维护性和可移植性的pages和document.。我列出了JSTL一些特别的特点。
JSTL提供了基于标签的遍历,条件以及其他一些功能,这些功能以前或者是直接在JSP中嵌入代码来实现的,或者是使用了自己创建的标签,非标准的标签库,或者是通过使用Servlet来代替JSP来实现的。
JSTL使用了EL(expression
language)语法
编写自定义标签相对其他一些JSP开发任务来说需要更多的精力与经验。JSTL通过两种方法来简化这些步骤:首先,如前所述,jstl能解决很多定制(自 定义)的tags的需要.(JSTL handles many common needs for custome tags)。其次,JSTL提供了一些机制使得编写你自定义的标签更简单,尤其是编写支持EL自定义标签的时候。
具体的JSTL特性与优点
下面简单的概括JSTL4个可用自定义标签库中三个标签库的一些优点,并且给出了不推荐使用数据库访问标签库(database
access library)的原因。同样我也讨论了使用EL的优点。
bitsCN_com关注网管是我们的使命
数据访问标签库(Database access
library)
JSTL提供了数据访问标签库,但是我很少用它,因为我强烈的认为不应该在JSP页面内直接访问数据库。如果在JSP中直接的访问数据库将会降低重用, 因为数据库访问的代码在使用数据库范围标签的JSP页面外是不可以被访问到的。在JSPs中直接的进行数据库访问将会加大表示层与数据层之间的耦合。严格 的分割意味着更好的模块化,复用性,以及更容易的满足表现层和数据层之间的规范(Disciplined
separation means more modularity, greater opportunity for reuse, and better
opportunities for specialization of presentation and database experts)。.我推荐在JSTL的其他三种标签库可以满足JSP开放人员的需求的时候使用这些标签库,但是我不推荐使用JSTL的数据库范围标签库 outside of prototypes
and the simplest Web applications。
JSTL 核心标签库(
利用servlet filter的特点
servlet filter是Servlet2。3规范中引入的,但是这些filter同样有利于JSP开发和维护。因为JSPs需要被转换成servlets, JSPs与servlet技术紧密相关。因此servlet规范的重要发展会影响到JSP的发展,对此你不应该感到奇怪。
Servlet filters是Intercepting Filter模式的J2ee实现,因此提供了这个模式的所提供的特点,包括更好的维护性,少的代码冗余以及更好的可移植性。这是因为:通常你需要加入服务 到每个jsp页面中,而现在可以通过将这些服务放到一个filter中。并且这些JSPs根本不需要这些filter的存在。因为在可插入的
filters与JSPs之间没有关联性,因此在filter中的修改将不会直接影响到JSPs。你可以使用filter链,使用不同的filter的组 合,每个filter用来实现不同的目的。
JSP网络应用中servlet filter的作用
下面 的两个例子说明了在基于JSP的网络应用中servlet filter的作用。在许多的安全配置中,每一个JSP页面都会检验会话ID和其他一些安全性来授权一个JSP调用。你可以将这些在每个JSP页面中的检 验代码移植到一个servlet filter中,并且确保这个filter在调用每个jsp页面之前被调用。这样就提高了JSPs的可维护性和可移植性。你可以仅仅的在这一个 servlet中进行一些安全检验方面的修改,或者是在其中加入一些和安全相关的代码。而不是在每一个JSP页面中进行修改。如果将来整个安全机制改变 了,系统中唯一要修改的地方仅仅是这个filter,独立的JSP页面将不需要任何修改。 www.bitsCN.net网管博客等你来搏
在上一篇“JSP Best Practices”中,我推荐将异常信息存储到“Secondary
Storage”中,并且仅仅的提供给用户一个可以检索这些异常信息的一个标志(and
only providing the user with an identifier to search the storage for the entire
exception trace)。在这种情况下servlet
filter非常的有用。你可以通过配置来使网络应用(Web
Application)在调用异常JSP时自动的来执行用来记录异常日志的filter。Sevlet规范提出了许多的潜在的servlet
filter用法。
为JSPs的创建API文档(document.nbspthe APIs for your JSPs)
Java的许多悦人心意的特点之一便是它支持JavaDoc。通过JavaDoc可以快速而容易的为java代码提供Web-based的文档。不幸的是,javadoc工具不支持JSP,并且JSP规范没有“唤起”一个方法来提供“JSP APIs”。
什么是JSP API?
能够不通过阅读JSP的全部的代码就能够快速的确定一些JSP方面是非常之有用的。比方说,你需要知道哪些变量是绑定到会话(session),请求 (request)和应用(application)的范围,并且这些变量是具体的被绑定到了具体的哪一个范围之上。另外一个JSP
API用处的例子是在JSP segment之中,segment需要知道在被包含的时候,调用它们的JSP中已经声明和制定了哪些变量(Another example of useful JSP API
information is denoting in JSP segments which variables they require the
calling JSP to have declared and defined when including them)。
bitsCN.com中国网管联盟
JSP规范没有涉及 关于如何的建立JSP API的文档。Sun的JSP 1.x 代码公约文档讨论将注释和作者,版权,以及描述的信息一起写在JSPs的上部,但是我喜欢更详细的记录JSPs的期望的输入(but
I like to document.nbspmy JSPs'
expected inputs more thoroughly)。
因为JSP规范中 没有涉及到这些,因此没有一个标准的用来注释JSP API。一个方法是在JSP中使用java代码(scriptlets)并且在代码中嵌入javadoc形式的注释(/**
javadoc comment */)。尽管我很少在JSPs中使用java代码,但是这是在服务器端保留这些注释的最简单的方法。使用XML/HTML风格的注释会将JSP API暴露在客户端,这是一个很不好的方法。
我知道有两种免费可以使用的产品可以用来为你的JSPs做注释,SourceForge.net 的JspDoc以及OSDN(Open
Source Development Network)的Freshmeat.net的JSPDoc。(关于两种工具的详细情况见resource【http:
//www.javaworld.com/javaworld/jw-07-2003/jw-0725-morejsp-p3.html#resources】). 这里我将简要的介绍一下这两个工具。
JspDoc(SourceForge)
SourceForge 的JspDoc可以用来为JSPs生成Javadoc风格的文档。这个工具通过将XML-Compliant的标签放入到Javadoc风格的注释 (/** */)之中,而这些注释是放在了JSP page的java代码中。这个工具的缺点是目前它仅仅支持JSP pages,尽管对JSP document.支持已经在计划列表中。 www.bitsCN.net网管博客等你来搏
这个工具还提供了转换JSP pages到JSP document.功能。因为我从一开始就编写JSP document.因为我没有用过这项功能,但是对于想从JSP pages转换到JSP document.用户来说,这是一个很好的工具。还要另外一个功能就是将JSP
document.换到JSP pages。
JSPDoc(Freshmeat.net)
Freshmeat的JSP 文档生成器
JSPDoc从JSPs中抽取信息来创建Javadoc风格的基于Web的文档页面。这个工具的一个优点是它能够将产生的JSP文档与用Javadoc工 具产生的java类的文档结合起来。缺点是,为了产生注释要求有一个相当严格的注释结构。这个特殊的语法使用了Javadoc的(/** */)但是并不能够识别@符号,而@在标准javadoc是有一定的含义的。另一个缺点就是这个工具不支持XML-compliant的JSP
document.而是要求用<%%>的语法结构。This product is available
under the Mozilla public license.
JSP document.tion for JSP document. 因为JspDoc和JSPDoc都不支持JSP document.我利用JSP document.XML-compliance的特性来产生Javadoc形式的文档。使用XSLT stylesheet,可是很容易的来为JSP document.建HTML页面形式的注释文档。而且不需要自定义的解析。因为当你的JSP是一个正确的XML文档时有标准的工具(比方Xalan)能 够进行这些处理。
当你在浏览器中键入URL来执行JSP时,JSP在以HTML的形式提交给用户之前需要经历一系列的处理。正是因为这些处理,因此当第一次请求jsp
的时候需要的时间要比其后对这个jsp页面的访问需要的时间要长很多。很多的开发人员都知道在发布的时候预编译JSPs的重要性,同样的,在开发阶段进行 预编译也是很有用的。
你可以在编译代码的阶段,在编译与JSP相关的javabean、自定义标签处理类(custom tag handler classes)、其他一些相关的类以及servlet的同时预编译JSP。这样只需要进行一次的编译,减少了某一个时间内需要的编译的时间。对于开发人 员来说,这非常有好处,因为在等待编译的时候,他们很容易分心。因此一次性的进行所以的编译相对与只是在请求jsp的时候才进行编译是很有好处的。
预编译可以发现语法问题(parser problem)以及其他一些翻译时期(translation-time)出现的问题。这些问题通常需要多个步骤才能够定位。这样对于开发人员来说是有 意义的,这样开发人员就不需要通过浏览多个页面后才可以定位存在问题的页面了。如果使用JSP
document.话,那么还可以在预编译的时候来验证JSP document.结构。
预编译的另一个好处是可以在发布的war文件中包含你的编译了的JSP版本,而不是实际的JSP源代码。JSP进行编译后,就可以以.class文件包含在发布的产品中(这些.class文件名满足容器的供应商特定的命名约定)。 bitsCN_com
大多数的Java 2平台,J2EE以及一些java工具都支持JSP预编译,专业的网络容器也支持JSP预编译,尽管可能是通过一种非标准的命令或者界面。许多的网络容器 都支持命令行形式的JSP预编译,你可以在你的scripted builds中加入这些命令行。
组织文件和目录
下面的技术有助于JSP的开发与维护,能够使得你的JSP开发和维护更容易和高效:
l 组织Web的根目录
l 组织好WEB-INF目录,合理的使用子目录
l 以.jspf的扩展名来标识JSP
fragments(需要被include在其他jsp页面中的jsp文件,译者注)
l 使用IDE,ANT,以及其他一些自动生成工具
组织Web的根目录
你可以通过将所有的Web应用所有的文件直接的放到web的根目录下面,这个目录就是WEB-INF目录所在的目录。我推荐合理的组织这个目录,比方说 在其中加入jsp,html,css以及css等子目录。对于简单的应用来说,是否需要这样来划分目录还有争议但是对于大的网络应用来可以增强理解以及维 护性能。
组织WEB-INF目录
标签酷是在JSP开发中很有价值的资源。大的网络应用可能包含有几个 标签库比方说:JSTL标签库、Struts标签库以及其他的一些标签库。我推荐在WEB-INF目录下面建立一个tld子目录来存放这些标签库而不是将 这些标签库放在WEB-INF目录下面。这样可能会“淹没”了这个目录。
需要什么来搜一搜吧so.bitsCN.com
以.jspf的扩展名来标识JSP fragments
在最近版本的JSP规范中的JSP segments(以前版本称为JSP
fragments)即.jspf文件是不完整的JSPs,是用来被其他的JSP来包含的。JSP规范建议使用命名规范来区别“外层”的JSPs和JSP fragments/segments。通常将命名完整的“外层”的文件以“.jsp”为扩展名,而JSP fragments/segments以“.jspf”为扩展名,但是规范并没有要求这样做。我同样推荐将完整和“外层”的JSPs放在一个不同的目录下 面。
使用IDE,ANT及其他的一些自动工具
IDEs可以加速开发和部署的时间,并且减少书写以及其他的一些错误。有许多的IDE工具提供了J2EE工具和向导。这些工具同样同一些框架相集成(如Struts和JSTL标签库)。
Ant是defacto标准的创建和部署java和j2ee应用的工具。Ant提供了创建和部署应用时很多有用的特性,同样也支持创建和部署war以及 ear文件。许多工具内嵌支持Ant。当不能使用IDEs时,我任务Ant时必不可少的。其他一些工具也可能支持自动创建和部署,也能提供ant提供的特 性,但是ant一个最重要的特点就在于它的费用(免费)以及它支持很广泛。
同样我推荐Apache的Apache Maven,在考虑管理整个java项目时它也是一个很有用的产品。 bitsCN_com关注网管是我们的使命
重新考虑与规范不相容(nonspecification-compliant)的特性
Web Server偶尔会提供一些与供应商特定(vendor-specific)的特性,这些特性在开发时非常有用,可以提高性能、安全以及其他一些特性。在
有些情况下,使用这些与供应商相关(vendor-specific)的特性是合理的,因为它所带来的优点远远的超过了其所可能蕴涵的危险。然而你需要意 识到使用与供应商特定的特性时所蕴含的危险,因此在同样的情况下应该优先的考虑使用和规范相容的特性。记住,并不是所以的特性都是按照规范而“呼唤”出来 的,在这种情况下,任何一个供应商的实现都是私有的。
技术的依赖并不总是使得供应商特点的特性蕴含危险。特定的Web
servers供应商提供的自定义标签库可能在所有的支持自定义标签的Web
server都可以使用,这种情况下你需要注意的是版权(licensing
issues)问题了。
最佳实践(best practice)依赖与变换Web servers的可能性。当我不使用tomcat做为web server时,我通常会在其他别的web servers上面部署基于j2ee的网络应用来检验规范的相容性。需要记住的一点是,即使你一直使用一种web
server,随着时间的发展,使用供应商特定的特性也存在危险。因为j2ee规范不断的进步,在某一个特定的供应商以他们特有的方式实现了一定的特性的 时候,j2ee规范可能就会以一种标准的形式来定义这个特性。这种情况下,这个供应商就会转向这个同一的标准。 play.bitsCN.com累了吗玩一下吧
使用XHTML语法
在“JSP Best Practices”中,我推荐在JSPs中使用HTML的最佳实践(best
pratices)。更近一步,我发现在创建JSP document.XHTML规范提供很有用的HTML标签语法(I
now find that the XHTML specification offers the most useful version of HTML
tag syntax in authoring JSP document.),XHTML使得更容易的来创建XML相容的JSP document.甚至JSPs
page的作者也发现了在JSPs中使用XHTML是有好处的。
因为完全的XML相容,XHTML语法比
HTML遵守个严格的规则。标准的HTML和XHTML标签的不同见:World Wide Web Consortium's XHTML 1.0 pages.(http://www.javaworld.com/javaworld/jw-07-2003/jw-0725-morejsp-
p4.html#resources.)
只能做的更好(It only gets
better)
JSP技术是用来简化灵活的web开发的。近来产生JSTL技术延续了这一趋势。甚至servlet方面规范的进步也大大的方便了JSP的开发。JSP和 servlet规范的进步、一些新的工具的产生、JSP编码标准的共享都使得高可维护的JSP的开发比以前更加的容易。