JavaServer Pages
JavaServer Pages能产生强大的动态HTML页面。JSPs是直接从Java servlets扩展的,这可以让开发人员在JSP中嵌入JAVA逻辑代码。JSP文件必须以后缀.jsp结尾。下面的代码是一个简单的JSP文件,如下:
<HTML>
<BODY>
<% out.println("HELLO JSP READER"); %>
</BODY>
</HTML>
看起来和HTML文件差不多,只是添加了标记来包含.JAVA代码。源代码的文件为hello.jsp,把文件复制到WEB应用中进行部署。当请求一个JSP文件时,JSP引擎会进行处理。当JSP文件第一次被请求时,它被解析成servlet,被编译后驻留于内存。用这个生成的servlet来处理客户端的请求,并返回结果到客户端。对于以后的请求,服务器会检验JSP文件是否被改变。如果没有改变,服务器调用已经生成的servlet对象。如果JSP文件被修改,JSP引擎会重新编译JSP文件以生成新的Servlet。
注意:实质上JSP就是由HTML和JAVA代码组成的。因此它们可获得servlet一样的资源和功能。
JavaServer Page的组成
这节我们讨论JSP的组成,包括:标签,脚本,隐含对象和标准活动。
(directives, scripting, implicit objects, and standardactions.)
JSP标签(Directives)
JSP标签是JSP页面中提供全局信息的元素。标签的一个例子导入JAVA类列表到JSP中。JSP标签的语法如下:
<%@ directive {attribute="value"} %>
page 指令
表示如下:
<%@ page {attribute="value"} %>
表2.2定义了page指令的属性。
Table 2.2 defines the attributes for the page directive.
属性
说明
language=”scriptingLanguage”
告诉服务器什么语言会被编译,目前只支持JAVA
extends=”className”
当你扩展JSP时,指明JSP的父类。这么做会限制JSP/Servlet的自由度,因此不推荐。
import=”importList”
定义导入到JSP中的JAVA类包,用分号来分隔不同的类包。
session=”true|false”
定义是否在JSP中使用session。缺省值为true。
buffer=”none|size in kb”
是否对输出流进行缓冲。缺省值为8KB.
autoFlush=”true|false”
定义输出流是否会被自动输出,不管缓冲是否已满。缺省值为true。
isThreadSafe=”true|false”
告诉JSP引擎这个页面同时可为多个请求服务。缺省值为true。如果设置为false,只能被用于单线程。
info=”text”
通过调用Servlet.getServletInfo()方法访问JSP页面的表示信息
errorPage=”error_url”
表示相应地址的JSP页面来处理抛出的JSP异常。
isErrorPage=”true|false”
表明JSP页面是否有一个错误处理页面,缺省值为false。
contentType=”ctinfo”
表示发送到客户端的网际协议和字符集。
下面的代码片段包含了page指令,导入了java.util包
<%@ page import="java.util.*" %>
include指令
include指令被用来插入文本或者JSP文件。语法如下:
<%@ include file="relativeURLspec" %>
这个file属性通常为HTML文件或者JSP文件。被引用的文件必须为本WEB应用中的。例子如下:
<%@ include file="header.jsp" %>
注意:因为include指令在载入时只转换一次。因此,如果包含的资源改变,这个改变不会体现出来。即如果例子中header.jsp文件改变,当前页(包含header.jsp的页面)显示时并不会改变。
.
taglib指令
taglib指令用来包含自定义标签库,通过URI和关联的前缀来唯一的区分自定义标签。
注意:如果不熟悉JSP自定义标签,你可以学习作者的另一本书“Mastering JSP Custom Tags and Tag Libraries”。
taglib指令显示如下:
<%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %>
taglib在表2.3中描述:
属性
定义
uri
URI是自定义标签的唯一名
prefix
前缀被用来区分自定义标签的实例
下面是taglib的例子:
<%@ taglib uri="http://jakarta.apache.org/taglibs/random-1.0" prefix="rand"%>
JSP脚本
JSP中的脚本是直接绑定到HTML中的JAVA代码片段。
在JSP中有三种脚本语言组件可被调用,每种组件出现于相应的位置。
声明
声明用于定义JAVA变量和方法。JSP声明必须有声明语句。当JSP页第一次被载入时,JSP声明被初始化。初始化后,它们被用于同一JSP页面中的声明,表达式,脚本。语法如下:
<%! declaration %>
一个简单的变量声明:
<%! String name = new String("BOB"); %>
一个简单的方法声明:
<%! public String getName() { return name; } %>
为了更好的理解声明,让我们把声明放到JSP文件中。这个简单的文件代码如下:
<HTML>
<BODY>
<%! String name = new String("BOB"); %>
</BODY>
</HTML>
当文件被载入时,JSP被转换成servlet代码,声明放在servlet的声明区域内。
它在所有的JSP组件中均可使用,相当于类的成员变量。
注意:所有的JSP声明定义为类水平的,因此JSP的所有表达式和脚本中均有效。
表达式
JSP表达式在容器中计算。它在请求时进行计算,计算结果插入到JSP文件的表达式位置上。如果表达式结果不能被转换成字符串,translation-time错误会产生。
表达式语法如下:
<%= expression %>
表达式代码片段:
Hello <B><%= getName() %></B>
JPS文件中的表达式:
<HTML>
<BODY>
<%! public String getName() { return "Bob"; } %>
Hello <B><%= getName() %></B>
</BODY>
</HTML>
脚本
脚本用来把所有的JSP元素放在一起,它们在请求时被执行。他们在所有的JSP组件中使用。脚本语法如下:Scriptlets are the JSP components that bring all the JSP elements together.
<% scriptlet source %>
当JSP脚本代码被转换成servlet代码时,它生成servlet的service()方法。下面的JSP代码片段用来向客户端打印出“Hello Bob”。
<HTML>
<BODY>
<% out.println("Hello Bob"); %>
</BODY>
</HTML>
你会注意到JSP脚本功能非常强大,在JSP中使用脚本来实现你的逻辑会使你的WEB应用很难管理。因为这个原因,导致了我们要创建定义的标签库。
JSP错误处理
象所有的开发方法一样,JSP需要一种比较完善的错误处理机制。JSP体系结构中提供了一种错误处理解决方案,它通过在JSP中专门指明处理错误的JSP文件来实现。
JSP错误出现最多的是运行时错误,它通常由JSP页面或则是被JSP页面调用的一些对象所引起的。请求时错误(Request-time errors)是因为异常抛出的,它可以在被调用的JSP页面中捕获和处理。异常若未被处理会被传送到客户端。
创建 JSP错误页面
下面创建的JSP错误页面只进行很简单的处理:创建简单的JSP页,告诉JSP引擎这是一个错误处理页面,你需要设置属性isErrorPage=true。代码如下:
列表2.6 errorpage.jsp.
----------------------------------------------------------------------------------
<html>
<%@ page isErrorPage="true" %>
Error: <%= exception.getMessage() %> has been reported.
</body>
</html>
第一行JSP代码告诉编译器,这个JSP页面是一个错误处理页面。
代码片段如下:
<%@ page isErrorPage="true" %>
第二段JSP代码使用了隐含异常对象来输出未在JSP页面中被捕获异常消息,这个隐含的异常对象在所有的JSP错误处理页面都可以使用。
使用JSP错误处理页面
为了查看错误处理页面是如何工作的,让我们来创建JSP页面,它包含一个未捕获的异常。JSP页面如下:
列表2.7: testerror.jsp.
------------------------------------------------------------------------------------
<%@ page errorPage="errorpage.jsp" %>
<%
if ( true ) {
// Just throw an exception
throw new Exception("An uncaught Exception");
}
%>
-----------------------------------------------------
注意:第一行代码设置isErrorPage=”errorpage.jsp”,是为了指明如果JSP页面出现异常,将由errorpage.jsp来处理异常。本例中JSP抛出Exception,将由errorpage.jsp来处理。
把testerror.jsp和errorpage.jsp复制到:
<CATALINA_HOME>/webapps/wileyapp/ 目录下, and open the testerror.jsp
在浏览器中打开,你可以看到浏览器中显示了异常。
隐含对象(Implicit Objects)
作为JSP开发人员,你经常会隐含的访问那些在所有的JSP文件中都可以使用的对象。
如果你使用了这些对象,它们会被JSP引擎分析出,并在生成servlet时插入到对应的位置。
Out对象
Out隐含对象来源于java.io.Writer类,它用于发送输出流到客户端。
最通用的时out.println()方法,它来打印文本信息到客户端浏览器。
列表2.8显示了使用out隐含对象的例子:
--------------------------------------------------------------------------
<%@ page errorPage="errorpage.jsp" %>
<html>
<head>
<title>Use Out</title>
</head>
<body>
<%
// Print a simple message using the implicit out object.
out.println("<center><b>Hello Wiley" +
" Reader!</b></center>");
%>
</body>
</html>
--------------------------------------------------------------------
为了执行这个例子,复制文件到
<CATALINA_HOME>/webapps/ wileyapp/ 目录下,在浏览器中输入如下地址:
http://localhost:8080/wileyapp/out.jsp
你会看到:Hello Wiley Reader!
Request对象
这个隐含对象来源于javax.servlet.http.HttpServletRequest接口。它被关联到每一个HTTP请求。常用它来访问请求参数。你可以调用request对象的带参数名称的getParameter()方法,它将返回一个和参数名称匹配的字符串。
Request对象的使用例子如下
列表2.9: request.jsp.
-----------------------------------------------------------------------
<%@ page errorPage="errorpage.jsp" %>
<html>
<head>
<title>UseRequest</title>
</head>
<body>
<%
out.println("<b>Welcome: " +
request.getParameter("user") + "</b>");
%>
</body>
</html>
----------------------------------------------------
JSP通过参数user调用request.getParameter()方法。这个方法寻找参数列表中的键值user来返回数据。在浏览器中输入如下:
http://localhost:8080/wileyapp/request.jsp?user=Robert
可以看到输出:Welcome:Robert。
Response对象
response隐含对象来源于javax.servlet.http.HttpServletResponse。response对象用于把取得的数据返回到客户端。这个隐含对象可以实现HttpServletRequest所有的功能,和你在servlet处理没有什么区别。Response对象经常用于向客户端输出信息。然而JSP API已经提供了一个流对象out来输出信息到客户端。
PageContext对象
PageContext对象提供访问JSP页面的命名空间。它也提供用来访问其他的JSP隐含对象。比较常用的是使用setAttribute() 和getAttribute()方法设置和寻找对象。
Session对象
Session对象来源于javax.servlet.http.HttpSession。它用于存储客户端请求的信息,因此它是有状态交互式的。
Session对象列表如下:
列表2.10: session.jsp.
-------------------------------------------------------------------------------------
<%@ page errorPage="errorpage.jsp" %>
<html>
<head>
<title>Session Example</title>
</head>
<body>
<%
// get a reference to the current count from the session
Integer count = (Integer)session.getAttribute("COUNT");
if ( count == null ) {
// If the count was not found create one
count = new Integer(1);
// and add it to the HttpSession
session.setAttribute("COUNT", count);
}
else {
// Otherwise increment the value
count = new Integer(count.intValue() + 1);
session.setAttribute("COUNT", count);
}
out.println("<b>You have accessed this page: "
+ count + " times.</b>");
%>
</body>
</html>
复制文件到
<CATALINA_HOME>/wileyapp/ 目录,在浏览器中输入地址:
http://localhost:8080/wileyapp/session.jsp
如果你刷新页面访问次数会增加。
Application对象
Application对象来源于javax.servlet.ServletContext,在本章的前面已讨论过ServletContext。Application对象用于访问存储在ServletContext中的全局范围的对象。Application对象的使用方法可以在本章前面部分看到,在次不做叙述。
Config对象
Config对象来源于ServletConfig,它包含了当前JSP/Servlet所在的WEB应用的配置信息。
Page对象
Page对象来源于当前被访问JSP页面的实例化。它实际使用的是JSP转换成的Servlet。
Exception对象
Exception对象用于捕获JSP抛出的异常。它只有在JSP页面属性isErrorPage=true时才可用。
作者:James Goodwill 翻译:周海方
欢迎转载,前提是注明出处和译者