在早期,开发网络数据库应用程序主要采用CGI(Common Gateway Interface)技术。编写CGI程序可以使用不同的程序语言,如Perl、Visual Basic、Delphi或C/C++等。虽然CGI技术已经发展成熟而且功能强大,但由于其编程困难、效率低下、修改复杂等缺陷,所以有被新技术取代的 技术。
在这样的背景下,新的技术纷纷面世,如ASP(Active Server Page)、PHP(Personal Home Page)、JSP(Java Server Page)等。其中,JSP被许多人认为是未来最有发展前途的动态网站技术。 JSP页面一般由HTML标签和JSP元素构成,其中的JSP元素则又是由“指令元素”、“脚本元素” 、“标准动作元素” 、“内置对象”四个部分组成。下面,就让我们一起来探究JSP的奥秘吧……一. 指令元素
可以把JSP理解为用来通知JSP引擎的消息。JSP不直接生成可见的输出,用JSP指令设置JSP引擎处理JSP页面的机制。
一般JSP指令用标签<> 表示,JSP指令包括page、include和taglib。page指令是针对当前页面的指令,而include指令用来指定如何包含另外一个文 件,taglib指令用来定义和访问自定义标记库。这三种指令通常都有默认值,这样开发人员就不必显式的使用每一个指令予以确认。 1. page指令 page指令的设置语法格式是:<%@ page attribute1=”value1” attribute2=”value2”…%> 下面介绍指令中包括的几个常用属性,并作简要说明。 l import import指令是所有page指令中,唯一可以多次设置的指令,而且累加每个设置。它用来指定jsp网页中所需要使用到的一些类。例如: <%@ page import=”java.io.*,java.util.Date”%> l session 定义当前页面是否参与http会话。当设置为”true”时,可以获得隐含名为session的对象,为”false”时,则不能。默认设置为”true”。 l contentType 设置jsp网页输出时数据时,所使用的字符压缩方式,以及所使用的字符集,当编写中文网页时,设置如下: < contentType=”text/html;charset=Gb2312”%> 此属性的默认值为”text/html;charset=ISO-8859-1”。 l buffer 设置jsp网页的缓冲区大小,默认为”8k”,如果设置为”none”,则表示不使用缓冲,所有的响应输出都将被PrintWriter直接写到ServletResponse中。 l isTreadSafe 定义当前页面是否支持线程安全。如果为”true”,则该页面可能同时收到jsp引擎发出的多个请求,反之,jsp引擎会对收到的请求进行排队,当前页面在同一时刻只能处理一个请求。默认为”true”。 l info 设置页面的文本信息,可以通过Servlet.getServletInfo()的方法获得该字符串。 l errorPage 定义指向另一个jsp页面的URL。当页面出现一个没有被捕获的异常时,错误信息将以throw语句抛出,而被设置为错误信息网页的jsp页面,将利用exception隐含对象,取得错误信息。 默认没有错误处理页面。 l isErrorPage 设置此jsp网页是否为错误处理页面。默认值为”false”。当设置为”true”时,jsp页面将可存取隐含的exception对象,并通过该对象取得从发生错误之网页所传出的错误信息。取得错误信息的语法如下: <% =exception.getMessage()%> 2 一个页面错误处理的例子 产生错误的页面文件为MakeError.jsp,处理错误的页面文件为ErrorPage.jsp,它们的源程序如下: MakeError.jsp<%@ page errorPage="ErrorPage.jsp"%>
产生错误页面 <% int i=8,j=0; out.println(ij); %> ErrorPage.jsp <%@ page isErrorPage="true"%> 错误处理页面 错误原因:<%=exception.getMessage()%>运行程序MakeError.jsp的结果如下:
2. include指令 使用include指令可以把其他的文本文件加入到当前的jsp页面,格式如下: <%@ include file=”header.inc”%> 如此,则在当前页面中加入header.inc源代码然后再编译整个文件。 可以使用include指令把一个页面分成不同的部分,最后合成一个完整的文件,使用jsp的include指令有助于实现jsp页面的模块化。 3. taglib指令 (略)二. 脚本元素
JSP规格提供了四种类型的脚本元素,包括:
l 声明 l 表达式 l 脚本 l 注释 下面分别对它们进行详细叙述。 1. 声明元素 声明用于定义jsp页面中的变量与函数,这些经过定义的变量和函数,将成为Servlet类的属性与方法(关于Servlet请参看后文)。声明并不会产生任何的数据输出,声明时可同时设置初始值,提供给其他的声明、表达式或脚本使用。 声明的语法格式为:<%!
//声明语句 %> 举例: <%! //此处定义的变量将成为此jsp页面的全局变量 int i = 0; static int j=100; String s = “注意”; %> <%! //此处定义的函数将成为此jsp页面的公共函数 Public int square(int i) { return(i*i); } %>2 jspInit函数与jspDestroy函数
若要在jsp页面开始执行时进行某些数据的初始化,可以利用jspInit函数完 成。此函数将在jsp页面被执行时调用,且当jsp页面重新整理时,并不会被再度执行。当关闭服务器时,jspDestroy函数将被执行,可以利用该函 数进行数据的善后处理工作。下面举个简单的例子说明,文件InitDes.jsp代码如下:<%@ page contentType="text/html; charset=GB2312"%>
<%! public void jspInit() { System.out.println("jspInit is called!"); }public void jspDestroy()
{ System.out.println("jspDestroy is called!"); } %> jspInit函数与jspDestroy函数的使用jspInit函数与jspDestroy函数的使用
首次执行此页面时,Resin服务器输出如下:
Resin 1.2.2 -- Tue Jan 16 09:53:18 PST 2001 http listening to *:8080 srun listening to 127.0.0.1:6802 jspInit is called! 刷新此页面数次后,Resin服务器输出仍然如上。 此时,如果关闭服务器,则输出如下: Resin 1.2.2 -- Tue Jan 16 09:53:18 PST 2001 http listening to *:8080 srun listening to 127.0.0.1:6802 jspInit is called! closing server jspDestroy is called! 由此,我们得到启发,在数据库的开发过程中,可以利用jspInit函数来进行数据库的连接工作,用jspDestroy函数来进行数据库的关毕工作。下面以一个分页显示数据库内容的程序为例子,让读者进一步体会jspInit与jspDestroy的功用与好处。 在Pages.jsp这个分页程序中,我们把数据库连接的动作写在jspInit函数中,这样,每一次重新整理页面时,就可以避免重新执行数据库的连接动作。如下:<%@ page contentType="text/html; charset=GB2312"
import="java.sql.*"%> <%! int PageSize = 2; //设置每张网页显示两笔记录 int ShowPage = 1; //设置欲显示的页数 int RowCount = 0; //ResultSet的记录笔数 int PageCount = 0; //ResultSet分页后的总页数 Connection con = null; Statement stmt = null; ResultSet rs = null;public void jspInit() //执行数据库与相关数据的初始化
{ try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //载入驱动程序类别con = DriverManager.getConnection("jdbc:odbc:test");
//建立数据库链接stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY); //建立Statement对象, 并设置记录指标类型为可前后移动rs = stmt.executeQuery("SELECT * FROM products");
//建立ResultSet(结果集)对象,并执行SQL语句rs.last(); //将指标移至最后一笔记录
RowCount = rs.getRow(); //取得ResultSet中记录的笔数
PageCount = ((RowCount % PageSize) == 0 ? (RowCountPageSize) : (RowCountPageSize)+1); //计算显示的页数 } catch(Exception ex) { System.out.println(ex.toString()); } }public void jspDestroy() //执行关闭各种对象的操作
{ try { rs.close(); //关闭ResultSet对象 stmt.close(); //关闭Statement对象 con.close(); //关闭数据库链接对象 } catch(Exception ex) { System.out.println(ex.toString()); } } %> 记录的分页显示记录的分页显示
<% String ToPage = request.getParameter("ToPage");
//判断是否可正确取得ToPage参数,
//可取得则表示JSP网页应显示特定分页记录的语句 if(ToPage != null) { ShowPage = Integer.parseInt(ToPage); //取得指定显示的分页页数 //下面的if语句将判断用户输入的页数是否正确 if(ShowPage > PageCount) { //判断指定页数是否大于总页数, 是则设置显示最后一页 ShowPage = PageCount; } else if(ShowPage <= 0) { //若指定页数小于0, 则设置显示第一页的记录 ShowPage = 1; } }rs.absolute((ShowPage - 1) * PageSize + 1);
//计算欲显示页的第一笔记录位置 %>目前在第 <%= ShowPage %>页, 共有 <%= PageCount %>页
<% //利用For循环配合PageSize属性输出一页中的记录 for(int i = 1; i <= PageSize; i++) { %>
商品名 | <%= rs.getString("product_name") %> | 价格 | <%= rs.getInt("price") %> | 描述 | <%= rs.getString("description") %> |
<% //下面的if判断语句用于防止输出最后一页记录时, //将记录指标移至最后一笔记录之后 if(!rs.next()) //判断是否到达最后一笔记录 break; //跳出for循环 } %> <% //判断目前所在分页是否为第一页, //不是则显示到第一页与上一页的超链接 if(ShowPage != 1) { //下面建立的各超链接将链接至自己, //并将欲显示的分页以ToPage参数传递给自己 %> <% }
//判断目前所在分页是否为最后一页,
//不是则显示到最后一页与下一页的超链接 if(ShowPage != PageCount) { //下面建立的各超链接将链接至自己, //并将欲显示的分页以ToPage参数传递自己 %><% } %>
到 value=<%= ShowPage%> > 页 |
执行后,结果如下图:
2. 表达式元素 表达式是一个简化了的out.println语句。 表达式的语法格式为: <%=//要输出的数据%> 举例: <%=square(5)%> 3. 脚本元素 脚本是java程序的一段代码,只要符合java语法的语句都可以写在这里,它是在请求时期执行的,它可以使用jsp页面所定义的变量、方法、表达式或JavaBeans。 脚本的语法格式为:<%
//java代码 %> 举例: <% if(age<18) { out.println(“你是未成年人!!!!”); } else { out.println(“你已经成年了!!!!”); } %>4. 注释元素
用来对程序进行说明注释。注释大体有下列三种格式: <%--服务器端注释--%>三. 标准动作元素
标准动作元素用于执行一些常用的JSP页面动作,例如:将页面转向、使用JavaBean、设置JavaBean的属性等。在JSP中,标准动作元素共有以下几种:
l l l l l l l 其中、、这三个是专门用来操作JavaBeans的。 下面分别介绍它们。 1. 动作用于传递参数,必须配合、、动作一起使用。 语法格式: 2. 动作用于动态加载HTML页面或者JSP页面。 语法格式: 在jsp页面中,可以利用下面的语法取得返回的参数: request.getParameter(“name1”); 若不传递参数时,则语法格式如下: 举例: a.jsp页面代码如下:
b.jsp页面代码如下:
名字1、;<%=request.getParameter("name1")%> 名字2、;<%=request.getParameter("name2")%> 执行结果如下: “include标准动作”和“include指令”的差别在于:“include标准动作”包含的页面在运行时被加入,而“include指令”在编译时就被加入了。 3. 动作用于将浏览器显示的页面导向到另一个HTML页面或者jsp页面。 语法格式: 当然,动作中也可以加入参数,其设置和获得参数的方法与类似。 4. 动作用于加载applet,用途与HTML语法中的及