快捷搜索:

困扰JSP的一些问题与解决方法

如今每一个应用servlets的开拓者都知道JSP,一种由Sun公司发现并花费大年夜量精力加以执行并建构在servlet技巧之上的web技巧。JSP将servlet中的html代码离开了出来,从而可以加速web利用开拓和页面掩护。实际上,由Sun宣布的官方"利用开拓模型"文档上说得更远: "JSP技巧应该被视为标准,而servlets在多半环境下可视为一种弥补。" ( Section 1.9, 1999/12/15听取意见版 )。

本文的目的在于听取对该申明的合理性的评估 -- 经由过程对照JSP和另一项基于servlets的技巧: template engines(模板引擎)。

直接应用Servlets的问题

起先,servlets被发现,全部天下都看到了它的良好。基于servlet的动态网页可以被快速履行,可以在多个办事器之间随意马虎转移, 并且可以和后台数据库完美地集成。 Servlets被广泛吸收获为一种web办事器真个首选平台。;

然则,平日经由过程简单要领即可实现的html代码现在却要让法度榜样员经由过程 out.println()调用每一行HTML行,这在实际的 servlet利用中成为了一个严重问题。 HTML内容不得不经由过程代码来实现, 对付大年夜的HTML页来说不啻是一项繁重费时的事情。别的,认真网页内容的职员不得不请开拓职员来进行所有的更新。为此,人们寻求这一种更好的办理要领。

JSP到!

JSP 0.90呈现了。在这种技巧中你可以将Java代码嵌入到HTML文件,办事器将自动为页面创建一个 servlet。 JSP被觉得是一种写servlet的简略单纯要领。所有HTML可以直接获得而不必经由过程out.println()调用,而认真页面内容的职员可以直接改动HTML而不必冒破坏Java代码的风险。;

然则,让页面美术设计师和开拓职员在同一文件上事情并不抱负,让Java嵌入HTML被证实是就象将HTML 嵌入Java一样令人为难。读取一堆很乱的代码仍旧是一件艰苦的工作。;

于是,人们在应用jsp方面变得成熟,更多地应用了JavaBeans。 Beans包孕了jsp所需的营业逻缉代码。JSP中的大年夜多半代码都可以掏出来放到bean中去,而只留下极少的标记用于调用bean。

近来,人们开始觉得这种要领下的JSP页面真的很象是视图(view)。它们成为一个用于显示客户端哀求的结果的组件。于是人们会想,为什么不直接对view发送哀求呢? 目标view假如对该哀求分歧适又将若何? 说到底,很多的哀求有多种可能来取得结果view视图。例如,同一哀求可能产天生功的页面,数据库例外掉足申报,或者是缺少参数的掉足申报。同一哀求可能孕育发生一个英文页面也可能是西班牙文页面,这取决于客户真个locale。为什么客户端必须直接将哀求发送给view?为什么客户端不应该将哀求发送给一些通用的办事器组件并让办事器来抉择JSP view的返回?;

这使很多人吸收了已被称为"Model 2"的设计, 这是在JSP 0.92中定义的基于model-view-controller的模型。在这种设计中,哀求被发送到一个servlet节制器,它履行了商业逻缉并孕育发生一个邻近的数据"model"来用于显示。这一数据随后经由过程内部送到一个JSP "view"来进行显示,这样看起来JSP页就象是一个通俗的嵌入的JavaBean。 可以根据认真节制的servlet的内部逻辑来选择适当的JSP页面进行显示。这样,JSP文件成为了一个漂亮的template view。这便是另一种成长,并被别的一些开拓者所推重至今.

进入Template Engines

应用template engine来代替平日目的的JSP, 接下去的设计将变得简单,语法更简单,掉足信息更易读,对象也更用户化。 一些公司已经做了这样的引擎,最闻名的可能是WebMacro (http://webmacro.org, from Semiotek),他们的引擎是免费的。;

开拓者应该清楚明了,选定一个template engine来取代JSP供给了这么一些技巧上风,这也恰是jsp的一些不够之处:

问题 #1: Java代码太模板化了

虽然被觉得是不好的设计,JSP仍试图将Java代码加入web页面。这有些象是Java曾经做的,即对C++的简化改动,template engines也经由过程将jsp中的较低层的源码移去来使之简化。Template engines推行了更好的设计。

问题 #2: 要求Java代码

在JSP页中要求写一些Java代码。例如,假设某页要抉择当前web利用中根的高低文从而导向其主页,

在JSP中最好应用如下Java代码:;

<a href="<%= request.getContextPath() %>/index.html">Home page</a>;

你可以试图避免 Java代码,而应用 <jsp:getProperty> 标记但这将给你六下难以涉猎的字串:;

<a href="<jsp:getProperty name="request";

property="contextPath"/>/index.html">HomePage</a>

应用template engine则没有Java代码和丢脸的语法。这里是同样要求下在WebMacro中的写法:;

<a href=".ContextPath;/index.html">Home page</a>

在WebMacro中, ContextPath 作为 template engines应用了其它的语法类型。;

再看另 一个例子,假设一个高档的"view"必要设定一个cookie来记任命户缺省的颜色设置设置设备摆设摆设 -- 这种义务看起来大年夜概只能由view而不是servlet节制器来完成。在JSP中要有这样的Java代码:

<% Cookie c = new Cookie("colorscheme", "blue"); response.addCookie(c); %>

在WebMacro中则没有Java代码:

#set .colorscheme = "blue"

作为着末一个离子,要是又要从新找回原本的cookie中的颜色设置设置设备摆设摆设。对付JSP,我们可以觉得也有一个响应的对象类来供给赞助,由于用getCookies()直接做这样低层的会变得好笑而且艰苦。在JSP中:

<% String colorscheme = ServletUtils.getCookie(request, "colorscheme"); %>

在WebMacro中没有对对象类的必要,平日是:.colorscheme.Value .对写jsp的图形艺术师,又是哪一种语法更轻易进修呢?

JSP 1.1 引入了自定义标记(custom tags)容许随意率性的和HTML相似的标记在JSP页面中在后台履行Java代码,这将具有必然的代价,但条件是要有一个广泛知晓的,全功能的,可以免费获得的,标准化的标记库。今朝还没有呈现这样的标记库。

问题 #3: 简单事情仍旧很累人

纵然是很简单的事情,例如包孕 header和 footer,在JSP中仍旧很很艰苦。 假设有一个 "header"和一个 "footer"模板要包孕到所有页面,而每一个模板要在content中包孕当前的页标题。;

在JSP中最佳法子是:;

<% String title = "The Page Title"%>;

<%@ include file="/header.jsp" %>;

...你的页面内容...;

<%@ include file="/footer.jsp" %>

页面设计者要记着不能漏掉第一行的分号并要将title定义为一个字符串。此外, /header.jsp和/footer.jsp必须在根目录下并且必须是可存取的完备文件。;

在WebMacro中包孕headers和footers做起来对照简单:

#set 24 = "The Page Title";

#parse "header.wm";

Your content here;

#parse "footer.wm"

这里对设计者来说没有要切记的分号或对title的定义, .wm文件可以放在可自定义的搜索路径下。

问题 #4: 很粗的轮回

在JSP中轮回很艰苦。这里是用JSP重复打印出每一个ISP工签字字。;

<%;

Enumeration e = list.elements();;

while (e.hasMoreElements()) {;

out.print("The next name is ");;

out.println(((ISP)e.nextElement()).getName());;

out.print("<br>");;

};

%>

大概什么时刻会有用户自定义标记来做这些轮回。对"if"也是如斯。JSP页可能看上去成了很古怪的java代码。而同时,webmacro轮回很漂亮:;

#foreach in {;

The next name is .Name <br>;

}

假如需要的话,#foreach指令可被自定义的 #foreach-backwards指令很轻易地取代。

用jsp的话很可能变这样:(这里是一个可能的 <foreach>标记)

<foreach item="isp" list="isps">;

The next name is <jsp:getProperty name="isp" property="name"/> <br>;

</foreach>

设计者当然地回选择前者。;

问题 #5: 无用的掉足信息

JSP常有一些令人惊疑的掉足信息。这是由于页面首先被转换成为一个servlet然后才进行编译。好的JSP 对象可以相对增添找到掉足位置的可能性,但纵然是最好的对象也无法使所有掉足信息都能轻易地被读懂。因为转化的历程,一些差错对对象来说可能根本弗成能被识别。

例如,假设JSP页面必要建立一个对所有页通用的标题。以下代码并没有错:

<% static String title = "Global title"%>

但Tomcat会供给以下掉足信息:;

work/%3A8080%2F/JC_0002ejspJC_jsp_1.java:70: Statement expected.;

static int count = 0;;

^;

此信息觉得以上脚本被放入 _jspService()措施而静态变量不容许放入措施中。该语法应该是 <%! %>。页面设计者很难读懂这些掉足信息。纵然最好的平台在这方面也做得很不敷。纵然所有 Java代码都从页中移出也无法办理问题。别的,以下表达式有什么错?

<% count %>;

tomcat给出:;

work/8080/_0002ftest_0002ejsptest_jsp_0.java:56: Class count not found in;

type declaration.;

count;

^;

work/8080/_0002ftest_0002ejsptest_jsp_0.java:59: Invalid declaration.;

out.write("\r\n");;

^

换句话说,只是遗掉了一个标记而已。应该是 <%= count %>。

因为template engine可以在template文件中直接孕育发生而没有任何戏剧性的向代码转化,以是可以异常轻易地给出适当的掉足申报。 依次类推,当c说话的敕令被打入Unix shell的敕令行, 你并不盼望shell 会天生一个C法度榜样来运行这个敕令,而只是必要shell简单地解释敕令并加以履行,如有差错也直接给出。

JSP的角色

当然地,JSP在将来一定会有其职位地方。纵然从名称上也可以看出JSP和ASP的相似性,它们只有一个字母的区别。以是假如要让应用asp的人们转向java,异常相似的jsp情况将对此起到很大年夜的推动感化,和asp维持这种对应关系所能起到的感化应该也是被推出jsp的设计者重点斟酌到的。;

然而这里想要强调的一点是:有利于转入新情况的事情者,以及实际上是否是应用该情况的最佳要领,这两者是有很大年夜不合的。

JSP日益显示出它正成为最紧张的java技巧之一, 它让人们脱离ASP的天下 -- 由此,Sun将支持这一强有力的商业case, Java相关技巧支持者也将给予更大年夜力的支持。

可是,这并非java平台的最佳办理规划。这将使java办理规划变得好象是没有java的办理规划了。

问题 #6: 必要一个编译器

JSP必要一个置放在webserver中的编译器。因为Sun回绝放弃包孕了他们的javac编译器的tools.jar库, 这此中就变得有问题了。Web办事器可以包孕进一个第三方的编译器如ibm的 jikes。但这样的编译器并不能在所有平台上顺利事情(用 C++写成的) 也晦气于建立纯Java 的web办事器。 JSP有一个预编译选项可以起到必然感化,只管并不完美。

问题 #7: 空间的挥霍

JSP耗损了额外的内存和硬盘空间。对办事器上每30K的JSP文件,必须要有响应的大年夜于30K的类文件孕育发生。实际上使得硬盘空间越发。斟酌到JSP文件随时可以很轻易地经由过程 <%@ include>包孕一个大年夜的数据文件,这样的关注有着很现实的意义。同时,每一个JSP的类文件数据必须加载到办事器的内存中,这意味着办事器的内存必须永世地将全部JSP文档树保存下去。少数一些JVM有能力将类文件数据从内存中移去;然则,法度榜样员平日无法节制这样的规则来从新申明,而且对大年夜的站点来说从新申明可能不是很有效。对template engines因为没有孕育发生第二个文件,以是节省了空间。Template engines还为法度榜样员供给对templates在内存中进行缓存的完全节制。

应用template engine也有一些问题:

Template的问题 #1: 没有严格定义

template engine该若何事情并没有严格定义。可是,但相对jsp来说,着实这并不很紧张,和 JSP不合的是,template engines对web办事器没有任何特殊要求 -- 任何支持servlet的办事器都可以支持template engines (包括API 2.0办事器如Apache/JServ,它们并不能完全支持 JSP)! 假如为最好的template engine设计供给康健的竞争本可以引起一场刺眼的改革,分外是有开放源码的匆匆进,(可以让思惟互相推动和匆匆进),那么本日的WebMacro就会象Perl一样,没有严格定义但公开源码组织的推动便是它的标准。

Template的问题 #2: 没有得到公认

Template engines并未被广泛知晓。JSP已经盘踞了极大年夜的商业市场,并且深入民心。而应用g template engines只能是一种未被懂得的替代技巧。

Template的问题 #3: 尚未调配好

Template engines还没有被高度地调配好。没有对template engine 和JSP两者进行机能测试和对照。理论上说一个调配齐全的template engine实现应该和一个调配好的JSP相匹配;然则,斟酌到第三方为jsp已经作出了这么深远的推动,结果只有jsp被很好地调配好了。

您可能还会对下面的文章感兴趣: