JSP 二讲
教 学 活 动 首 页
基 本 内 容 |
第 2 章 JSP 语法 |
教学目的与要求:通过本章的学习让学生了解SP 中的注释的使用方法;理JSP页面的基本结构;掌握变量和方法的声明方法,Java 程序片的使用,Java 表达式的使用,JSP指令标签和JSP动作标签的使用。 |
教学内容: 2.1 JSP 页面的基本结构 2.2 变量和方法的声明 2.3 Java 程序片 2.4 Java 表达式 2.5 JSP 中的注释 2.6 JSP 指令标签 2.7 JSP 动作标签 |
教学基本要求: 了解:JSP 中的注释 理解:JSP页面的基本结构 掌握:变量和方法的声明,Java 程序片,Java 表达式,JSP指令标签,JSP动作标签 |
教学重点教学难点: JSP页面的基本结构,变量和方法的声明, Java 程序片,Java 表达式, JSP指令标签, JSP动作标签 |
教学方法: 教学手段:多媒体教学和计算机程序演示 |
教学小结: (见教学进程) |
作业与思考:见课后习题 |
课后记载:
|
教 学 进 程
第2章 JSP语法 2.1 JSP页面的基本结构 在传统的HTML页面文件中加入java程序片和JSP标签就构成了一个JSP页面文件。一个JSP页面可由5种元素组合而成: (1)普通的HTML标记符。 (2)JSP标签:如,指令标签、动作标签。 (3)变量和方法的声明。 (4)Java 程序片。 (5)Java 表达式。 我们称(3)、(4)、(5)形成的部分为JSP的脚本部分。 当服务器上的一个jsp页面被第一次请求执行时,服务器上的JSP引擎首先将JSP页面文件转译成一个java文件,再将这个java文件编译生成字节码文件,然后通过执行字节码文件响应客户的请求。这个字节码文件的任务就是: 把JSP页面中普通的HTML标记符号,交给客户的浏览器执行显示。 JSP标签、数据和方法声明、Java程序片由服务器负责执行,将需要显示的结果发送给客户的浏览器。 Java 表达式由服务器负责计算,并将结果转化为字符串,然后交给客户的浏览器负责显示。 在下面的例子1中,客户通过表单向服务器提交三角形三边的长度,服务器将计算三角形的面积,并将计算的结果以及客户输入的三边长度返回给客户。为了讲解方便,下面的JSP文件加入了行号,它们并不是JSP源文件的组成部分。
(1)、(2)行是JSP指令标签。 (3)至(10)行是HTML标记,其中(7)到(10)行是HTML表单,客户通过该表单向服务器提交数据。 (11)至(13)行是数据声明部分,该部分声明的数据在整个JSP页面内有效。(14)至(42)行是Java程序片,该程序片负责计算面积,并将结果返回给客户。该程序片内声明的变量只在该程序片内有效。 (45)、(47)、(49)行是Java 表达式
例子1(效果如图2.1所示) Example2_1.jsp: (1) <%@ page contentType="text/html;charset=GB2312" %> (2) <%@ page import="java.util.*" %> (3) <HTML> (4) <BODY BGCOLOR=cyan><FONT Size=1> (5) <P> 请输入三角形的三个边的长度,输入的数字用逗号分割: (6) <BR> (7) <FORM action="Example2_1.jsp" method=post name=form> (8) <INPUT type="text" name="boy"> (9) <INPUT TYPE="submit" value="送出" name=submit> (10) </FORM> (11) <%! double a[]=new double[3]; (12) String answer=null; (13) %> (14) <% int i=0; (15) boolean b=true; (16) String s=null; (17) double result=0; (18) double a[]=new double[3]; (19) String answer=null; (20) s=request.getParameter("boy"); (21) if(s!=null) (22) { StringTokenizer fenxi=new StringTokenizer(s,",,"); (23) while(fenxi.hasMoreTokens()) (24) { String temp=fenxi.nextToken(); (25) try{ a[i]=Double.valueOf(temp).doubleValue(); (26) i++; (27) } (28) catch(NumberFormatException e) (29) {out.print("<BR>"+"请输入数字字符"); (30) } (31) } (32) if(a[0]+a[1]>a[2]&&a[0]+a[2]>a[1]&&a[1]+a[2]>a[0]&&b==true) (33) { double p=(a[0]+a[1]+a[2])/2; (34) result=Math.sqrt(p*(p-a[0])*(p-a[1])*(p-a[2])); (35) out.print("面积:"+result); (36) } (37) else (38) {answer="您输入的三边不能构成一个三角形"; (39) out.print("<BR>"+answer); (40) } (41) } (42) %> (43) <P> 您输入的三边是: (44) <BR> (45) <%=a[0]%> (46) <BR> (47) <%=a[1]%> (48) <BR> (49) <%=a[2]%> (50) </BODY> (51) </HTML> 2.2 变量和方法的声明 在“<%!”和“%>”标记符号之间声明变量和方法。 在“<%!”和“%>”标记符之间声明变量,即在“<%!”和“%>”之间放置Java的变量声明语句,变量的类型可以是Java 语言允许的任何数据类型,我们将这些变量称为JSP页面的成员变量。如,
<%! int a, b=10 , c; String tom=null,jerry=”love JSP”; Date date; %>
“<%!”和“%>”之间声明的变量在整个JSP页面内都有效,因为JSP引擎将JSP页面转译成Java 文件时,将这些变量作为类的成员变量。这些变量的内存空间直到服务器关闭才释放。当多个客户请求一个JSP页面时,JSP引擎为每个客户启动一个线程,这些线程由JSP引擎服务器来管理,这些线程共享JSP页面的成员变量,因此任何一个用户对JSP页面成员变量操作的结果,都会影响到其他用户。 下面的例子2利用成员变量被所有用户共享这一性质,实现了一个简单的计数器。
Example2_2.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY BGCOLOR=cyan><FONT size=1> <%!int i=0; %> <%i++; %> <P>您是第 <%=i%> 个访问本站的客户。 </BODY> </HTML>
在处理多线程问题时,我们必须注意这样一个问题:当两个或多个线程同时访问同一个共享的变量,并且一个线程需要修改这个变量时,我们应对这样的问题作出处理,否则可能发生混乱。在上面的例子2中,可能发生两个客户同时请求Example2_2.jsp页面。在Java语言中我们已经知道,在处理线程同步时,可以将线程共享的变量放入一个synchronized块,或将修改该变量的方法用synchronized来修饰。这样,当一个客户用synchronized块或synchronized方法操作一个共享变量时,其它线程就必须等待,直到该线程执行完该方法或同步块。下面的例子3对例子2进行了改进。 例子3 Example2_3.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <%! Integer number=new Integer(0); %> <% synchronized(number) { int i=number.intValue(); i++; number=new Integer(i); } %> <P>您是第 <%=number.intValue()%> 个访问本站的客户。 </BODY> </HTML> 在“<%!”和“%>”之间声明方法,该方法在整个JSP页面有效,但是该方法内定义的变量只在该方法内有效。这些方法将在Java程序片中被调用,当方法被调用时,方法内定义的变量被分配内存,调用完毕即可释放所占的内存。当多个客户同时请求一个JSP页面时,他们可能使用方法操作成员变量,对这种情况应给予注意。在下面的例子4中,通过synchronized方法操作一个成员变量来实现一个计数器。 例子4 Example2_4.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <%! int number=0; synchronized void countPeople() { number++; } %> <% countPeople(); //在程序片中调用方法。 %> <P><P>您是第 <%=number%> 个访问本站的客户。 </BODY></HTML> 在上面的例子4中,如果Tomcat服务器重新启动就会刷新计数器,因此计数又从0开始。在下面的例子5中,我们使用Java的输入输出流技术,将计数保存到文件。当客户访问该JSP页面时,就去读取这个文件,将服务器重新启动之前的计数读入,并在此基础上增1,然后将新的计数写入到文件;如果这个文件不存在(服务器没有作过重新启动),就将计数增1,并创建一个文件,然后将计数写入到这个文件(有关文件和输入输出流技术可参见第4章)。
例子5(效果如图2.3所示) Example2_5.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.io.*" %> <HTML> <BODY BGCOLOR=cyan><FONT Size=1> <%! int number=0; synchronized void countPeople()//计算访问次数的同步方法 { if(number==0) { try{ FileInputStream in=new FileInputStream("count.txt"); DataInputStream dataIn=new DataInputStream(in); number=dataIn.readInt(); number++; in.close(); dataIn.close(); } catch(FileNotFoundException e) { number++; try {FileOutputStream out=new FileOutputStream("count.txt"); DataOutputStream dataOut=new DataOutputStream(out); dataOut.writeInt(number); out.close();dataOut.close(); } catch(IOException ee){} } catch(IOException ee) { } } else {number++; try{ FileOutputStream out=new FileOutputStream("count.txt"); DataOutputStream dataOut=new DataOutputStream(out); dataOut.writeInt(number); out.close();dataOut.close(); } catch(FileNotFoundException e){} catch(IOException e){} } } %> <% countPeople(); %> <P><P>您是第 <%=number%> 个访问本站的客户。 <BODY> <HTML> 数学上有一个计算π的公式:π/4=1-1/3+1/5-1/7+1/9-1/11 … …。 下面的例子6中利用成员变量被所有客户共享这一特性实现客户帮助计算π的值,即每当客户访问Example2_6.jsp都参与了一次π的计算。
Example2_6.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY bgcolor=cyan><FONT Size=1> <%! double sum=0,i=1,j=1; long number=0; synchronized void 帮助计算PI() { number++; sum=sum+i/j; j=j+2; i=-i; } %> <% 帮助计算PI(); %> <P>您是第<%=number%>个访问者 <BR> <P>目前PI的计算结果是: <%=sum*4%> </BODY> </HTML> 可以在“<%!”和“%>”之间声明一个类,该类在JSP页面内有效,即在JSP页面的Java程序片部分可以使用该类创建对象。在下面的例子7中,我们定义了一个Circle类,该类的对象负责求圆的面积和周长。当客户向服务器提交圆的半径后,该对象负责计算面积和周长。 例子7(效果如图2.5所示) Example2_7.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <P> 请输入圆的半径: <BR> <FORM action="Example2_7.jsp" method=get name=form> <INPUT type="text" name="cat" value="1"> <INPUT TYPE="submit" value="送出" name=submit> </FORM> <%! public class Circle {double r; Circle(double r) {this.r=r; } double 求面积() {return Math.PI*r*r; } double 求周长() {return Math.PI*2*r; } } %> <% String str=request.getParameter("cat"); double r; if(str!=null) {r=Double.valueOf(str).doubleValue(); } else {r=1; } Circle circle=new Circle(r); //创建对象。 %> <P> 圆的面积是: <BR> <%=circle.求面积()%> <P> 圆的周长是: <BR> <%=circle.求周长()%> <HTML> <BODY> 2.3 Java 程序片 可以在“<%”和“%>”之间插入Java 程序片。一个JSP页面可以有许多程序片,这些程序片将被JSP引擎按顺序执行。在一个程序片中声明的变量称做JSP页面的局部变量,它们在JSP页面内的所有程序片部分以及表达式部分内都有效。这是因为JSP引擎将JSP页面转译成Java 文件时,将各个程序片的这些变量作为类中某个方法的变量,即局部变量。利用程序片的这个性质,有时候可以将一个程序片分割成几个更小的程序片,然后在这些小的程序片之间再插入JSP页面的一些其它标记元素。当程序片被调用执行时,这些变量被分配内存空间,所有的程序片调用完毕,这些变量即可释放所占的内存。当多个客户请求一个JSP页面时,JSP引擎为每个客户启动一个线程,一个客户的局部变量和另一个客户的局部变量被分配不同的内存空间。因此,一个客户对JSP页面局部变量操作的结果,不会影响到其它客户的这个局部变量。 下面例子8中的程序片负责计算1到100的连续和。
Example2_8.jsp <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY bgcolor=cyan><FONT size=1> <%! long continueSum(int n) { int sum=0; for(int i=1;i<=n;i++) { sum=sum+i; } return sum; } %> <P>1到100的连续和:<BR> <% long sum; sum=continueSum(100); out.print(""+sum); %> </BODY> </HTML> 下面的例子9将例子8中的程序片分割成几部分。 例子9(效果如图2.7所示) Example2_9.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY bgcolor=cyan><Font size=1> <%! long continueSum(int n) { int sum=0; for(int i=1;i<=n;i++) { sum=sum+i; } return sum; } %> <P> 声明了一个long型变量sum: <% long sum; %> <P> 然后调用方法continueSum, <% sum=continueSum(101); %> <P> 将调用方法continueSum得到的值显示到客户: <BR> <P>1到101的连续和是: <%= sum %> <% if(sum>=5050) {%> <P>您计算的项数超过100项了。 <%} else {%> <P>您计算的项数没有超过100项。 <% } %> </Font> </BODY> </HTML>
下面例子10的程序片负责读取服务器上的一个文件,并将文件的内容显示给客户。
Example2_10.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.io.*" %> <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.io.*" %> <HTML> <BODY bgcolor=cyan><FONT size=1> <% try{ File f=new File("D:/test","A.txt"); FileReader in=new FileReader(f); BufferedReader buffer=new BufferedReader(in); String s=null; while((s=buffer.readLine())!=null) { out.print(s+"<BR>"); } in.close(); buffer.close(); } catch(IOException ee) {out.print("文件不存在");} %> </BODY> </HTML> 2.4 表达式 可以在“<%=”和“%>”之间插入一个表达式(注意:不可插入语句,“<%=”是一个完整的符号,“<%”和“=”之间不要有空格),这个表达式必须能求值。表达式的值由服务器负责计算,并将计算结果用字符串形式发送到客户端显示。 下面的例子11计算表达式的值。
Example2_11.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY bgcolor=cyan><FONT size=1> <P> Sin(0.9)除以3等于 <%=Math.sin(0.90)/3%> <p>3的平方是: <%=Math.pow(3,2)%> <P>12345679乘72等于 <%=12345679*72%> <P> 5的平方根等于 <%=Math.sqrt(5)%> <P>99大于100吗?回答: <%=99>100%> </BODY> </HTML> 2.5 JSP中的注释 注释可以增强JSP文件的可读性,并易于JSP文件的维护。JSP中的注释可分为两种 (1) HTML注释:在标记符号“<!--”和“-->”之间加入注释内容: <!-- 注释内容 --> JSP引擎把HTML注释交给客户,因此客户通过浏览器查看JSP的源文件时,能够看到HTML注释。 (2) JSP 注释:在标记符号“<%--”和“--%>”之间加入注释内容: <%-- 注释内容 --%> JSP引擎忽略JSP注释,即在编译JSP页面时忽略JSP注释。 例子12 Example2_12.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <P> 请输入三角形的三个边a,b,c的长度: <BR> <!-- 以下是HTML表单,向服务器发送三角形的三个边的长度 --> <FORM action="Example2_12.jsp" method=post name=form> <P>请输入三角形边a的长度: <INPUT type="text" name="a"> <BR> <P>请输入三角形边b的长度: <INPUT type="text" name="b"> <BR> <P>请输入三角形边c的长度: <INPUT type="text" name="c"> <BR> <INPUT TYPE="submit" value="送出" name=submit> </FORM> <%--获取客户提交的数据--%> <% String string_a=request.getParameter("a"), string_b=request.getParameter("b"), string_c=request.getParameter("c"); double a=0,b=0,c=0; %> <%--判断字符串是否是空对象,如果是空对象就初始化--%> <% if(string_a==null) {string_a="0";string_b="0";string_c="0"; } %> <%--求出边长,并计算面积--%> <% try{ a=Double.valueOf(string_a).doubleValue(); b=Double.valueOf(string_b).doubleValue(); c=Double.valueOf(string_c).doubleValue(); if(a+b>c&&a+c>b&&b+c>a) {double p=(a+b+c)/2.0; double mianji=Math.sqrt(p*(p-a)*(p-b)*(p-c)); out.print("<BR>"+"三角形面积:"+mianji); } else {out.print("<BR>"+"您输入的三边不能构成一个三角形"); } } catch(NumberFormatException e) {out.print("<BR>"+"请输入数字字符"); } %> </BODY> </HTML> 2.6 JSP 指令标签 page 指令用来定义整个JSP页面的一些属性和这些属性的值。例如,我们可以用page指令定义JSP页面的contentType属性的值是"text/html;charset=GB2312",这样,我们的页面就可以显示标准汉语。如,
<%@ page contentType="text/html;charset=GB2312" %>
page 指令的格式:
<%@ page 属性1= “属性1的值” 属性2= “属性2的值” ……%>
属性值总是用单引号或引号双号括起来,例如:
<%@ page contentType="text/html;charset=GB2312" import="java.util.*" %>
如果为一个属性指定几个值话,这些值用逗号分割。page指令只能给import属性指定多个值;其它属性只能指定一个值。 例如: <%@ page import="java.util.*" ,"java.io.*" , "java.awt.*" %>
当你为import指定多个属性值时,JSP引擎把JSP页面转译成的java文件中会有如下的import语句:
import java.util.*; import java.io.*; import java.awt.*;
在一个JSP页面中,也可以使用多个page指令来指定属性及其值。需要注意的是:可以使用多个page指令给属性import几个值,但其它属性只能使用一次page指令指定该属性一个值。如,
<%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.util.*" %> <%@ page import="java.util.*", "java.awt.*" %>
注:下列用法是错误的 <%@ page contentType="text/html;charset=GB2312" %> <%@ page contentType="text/html;charset=GB2312" %> 尽管指定的属性值相同,也不允许2次使用Page 给contentType属性指定属性值, 注:page指令的作用对整个页面有效,与其书写的位置无关,但习惯把page指令写在JSP页面的最前面。
(1)language属性 定义JSP页面使用的脚本语言,该属性的值目前只能取"java"。 为language属性指定值的格式:
<%@ page language="java" %>
language属性的默认值是"java",即如果你在JSP页面中没有使用page指令指定该属性的值的话,那么,JSP页面默认有如下page指令:
<%@ page language="java" %>
(2)import 属性: 该属性的作用是为JSP页面引入Java核心包中的类,这样就可以在JSP页面的程序片部分、变量及函数声明部分、表达式部分使用包中的类。可以为该属性指定多个值,该属性的值可以是Java某包中的所有类或一个具体的类,例如:
<%@ page import="java.io.*", "java.util.Date" %>
JSP页面默认import属性已经有如下的值:
" java.lang.*"、 "javax.servlet.*"、"javax.servlet.jsp.*"、"javax.servlet.http.*"。
(3)contentType 属性: 定义JSP页面响应的MIME(Multipurpose Internet Mail Extention)类型和JSP页面字符的编码。属性值的一般形式是: “MIME类型”或 “MIME类型;charset=编码”,如:
<%@ page contentType="text/html;charset=GB2312" %>
contentType 属性的默认值是"text/html ; charset=ISO-8859-1"。
(4)session 属性: 用于设置是否需要使用内置的session对象。 session的属性值可以是true或false,session属性默认的属性值是true。 (5)buffer 属性: 内置输出流对象out负责将服务器的某些信息或运行结果发送到客户端显示,buffer属性用来指定out设置的缓冲区的大小或不使用缓冲区。 buffer属性可以取值 “none”,设置out不使用缓冲区。Buffer属性的默认值是8kb。例如:
<%@ page buffer= “24kb” %>
(6)auotFlush 属性 指定out的缓冲区被填满时,缓冲区是否自动刷新。 auotFlush可以取值true或false。auotFlush属性的默认值是true。当auotFlush属性取值false时,如果out的缓冲区填满时,就会出现缓存溢出异常。当buffer的值是 “none”时,auotFlush的值就不能设置成false。 (7)isThreadSafe 属性 用来设置JSP页面是否可多线程访问。 isThreadSafe的属性值取true或false。当isThreadSafe属性值设置为true时,JSP页面能同时响应多个客户的请求;当isThreadSafe属性值设置成false时,JSP页面同一时刻只能处理响应一个客户的请求,其他客户需排队等待。isThreadSafe属性的默认值是true。 (8)info 属性: 该属性为JSP页面准备一个字符串,属性值是某个字符串。例如,
<%@ page info= “we are students” %>
可以在JSP页面中使用方法:
getServletInfo();
获取info属性的属性值。 注:当JSP页面被转译成Java文件时,转译成的类是Servlet的一个子类,所以在JSP页面中可以使用Servlet类的方法:getServletInfo()。 下面的例子13使用getServletInfo()方法获取info的属性值。 例子13(效果如图2.10所示) Example2_13.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page info="我!张惠妹" %> <HTML> <BODY bgcolor=cyan><FONT Size=1> <P> 谁呀? <% String s=getServletInfo(); out.print("<BR>"+s); %> </BODY> <HTML> 如果需要在JSP页面内某处整体嵌入一个文件,就可以考虑使用这个指令标签。该指令标签语法如下:
<%@ include file= “文件的名字” %>
该指令标签的作用是在JSP页面出现该指令的位置处,静态插入一个文件。被插入的文件必须是可访问和可使用的,即该文件必须和当前JSP页面在同一Web服务目录中。所谓静态插入,就是当前JSP页面和插入的部分合并成一个新的JSP页面,然后JSP引擎再将这个新的JSP页面转译成Java类文件。因此,插入文件后,必须保证新合并成的JSP页面符合JSP语法规则,即能够成为一个JSP页面文件。比如,如果一个JSP页面使用include指令插入另一个JSP文件,被插入的这个JSP页面中有一个设置页面contentType属性的page指令:
<%@ page contentType="text/html;charset=GB2312" %>,
而当前JSP 页面已经使用page指令设置了contentType的属性值,那么新合并的JSP页面就出现了语法错误,当转译合并的JSP页面到Java文件时就会失败。 下面的例子14在JSP页面静态插入一个文本文件:Hello.txt,该文本文件的内容是:“你们好,很高兴认识你们呀!”。该文本文件必须和当前JSP页面在同一Web服务目录中。 例子14(效果如图2.11所示) Example2_14.jsp: <%@ page contentType="text/html;charset=GB2312" %> <html> <BODY bgcolor=cyan> <H3> <%@ include file="Hello.txt" %> </H3> </BODY> </HTML>
Example2_14_1.jsp: <%@ page contentType="text/html;charset=GB2312" %> <html> <BODY> <H3> 你们好,很高兴认识你们呀! </H3> </BODY> </HTML> 注:在Example2_14.jsp被转译成Java文件后,如果你对插入的文件Hello.txt进行了修改,那么必须要重新将Example2_14.jsp转译成java文件(重新保存页面,然后再访问该页面即可),否则只能看到修改前的Hello.txt的内容。 下面的例子15在JSP页面Example2_15.jsp中静态插入一个JSP文件:Computer.jsp。 Computer.jsp: <FORM action="" method=post name=form> <INPUT type="text" name="ok"> <BR><INPUT TYPE="submit" value="送出" name=submit> </FORM> <% String a=request.getParameter("ok"); if(a==null) { a="1"; } try{ double number=Integer.parseInt(a); out.print("<BR>"+Math.sqrt(number)); } catch(NumberFormatException e) { out.print("<BR>"+"请输入数字字符"); } %> 例子15(效果如图2.12所示) Example2_15.jsp: <%@ page contentType="text/html;charset=GB2312" %> <html> <BODY Bgcolor=cyan><FONT size=1> <P>请输入一个正数,点击按钮求这个数的平方根。 <CENTER> <%@ include file="Computer.jsp"%> </CENTER> </BODY> </HTML> 注:Example2_15.jsp等同于下述JSP文件:Example2_15_1.jsp。 Example2_15_1.jsp: <%@ page contentType="text/html;charset=GB2312" %> <html> <BODY Bgcolor=cyan><FONT size=1> <P>请输入一个正数,点击按钮求这个数的平方根。 <CENTER> <FORM action="" method=post name=form> <INPUT type="text" name="ok"> <BR><INPUT TYPE="submit" value="送出" name=submit> </FORM> <% String a=request.getParameter("ok"); if(a==null) { a="1"; } try{ double number=Integer.parseInt(a); out.print("<BR>"+Math.sqrt(number)); } catch(NumberFormatException e) { out.print("<BR>"+"请输入数字字符"); } %> </CENTER> </BODY> </HTML> 2.7 JSP 动作标签 动作标签是一种特殊的标签,它影响JSP运行时的功能。 include 动作标签:
<jsp:include page= “文件的名字”/> 或 <jsp:include page= “文件的名字”> </jsp:include>
该动作标签告诉JSP页面动态包含一个文件,即JSP页面运行时才将文件加入。与静态插入文件的include指令标签不同,当JSP引擎把JSP页面转译成Java文件时,不把JSP页面中动作指令include所包含的文件与原JSP页面合并一个新的JSP页面,而是告诉Java解释器,这个文件在JSP运行时(Java文件的字节码文件被加载执行)才包含进来。如果包含的文件是普通的文本文件,就将文件的内容发送到客户端,由客户端负责显示;如果包含的文件是jsp文件,JSP引擎就执行这个文件,然后将执行的结果发送到客户端,并由客户端负责显示这些结果。 注:include动作标签与静态插入文件的include指令标签有很大的不同,动作标签是在执行时才对包含的文件进行处理,因此JSP页面和它所包含的文件在逻辑和语法上是独立的;如果你对包含的文件进行了修改,那么运行时看到所包含文件修改后的结果,而静态include指令包含的文件如果发生了变化,我们必须要重新将JSP页面转译成java文件(可将该JSP页面重新保存,然后再访问,就可产生新的转译Java文件),否则只能看到所包含的修改前的文件内容。 注:书写include动作标签:<jsp:include page…../>时要注意:“jsp”、“:”、“include”三者之间不要有空格。 下面的例子16动态包含两个文件:image.html和Hello.txt。我们把Example2_16.jsp页面保存到Tomcat\Jakarta-tomcat-4.0\webapps\root,在root下又新建立了一个文件夹Myfile,Hello.txt存放在MyFile文件夹中,image.html存放在root下
Hello.txt: <H4>你好,祝学习进步! <BR>学习JSP要有Java语言的基础。 <BR>要认真学习JSP的基本语法。 </H4>
image.html: <image src="tom1.jpg">
例子16(效果如图2.13所示) Example2_16.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY BGCOLOR=Cyan><FONT Size=1> <P>加载的文件: <jsp:include page="Myfile/Hello.txt"> </jsp:include> <P>加载的图象: <BR> <jsp:include page="image.html"> </jsp:include> </BODY> </HTML> 由于动作指令include是动态地包含一个文件,因此客户可以通过HTML表单提交需要包含的文件的名字。在下面的例子17中,我们用Java语言中的File类列出了Tomcat\Jakarta-tomcat-4.0\webapps\root\Myfile下的所有的jsp文件,客户通过表单,提交要加载的文件的全名。 例子17(效果如图2.14所示) Example2_17.jsp: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import ="java.io.*" %> <%! class FileJSP implements FilenameFilter { String str=null; FileJSP(String s) {str="."+s; } public boolean accept(File dir,String name) { return name.endsWith(str); } } %> <BODY bgcolor=cyan><FONT Size=1> <P>下面列出了服务器上的一些jsp文件 <% File dir=new File("d:/Tomcat/Jakarta-tomcat-4.0/webapps/root/Myfile"); FileJSP file_jsp=new FileJSP("jsp"); String file_name[]=dir.list(file_jsp); for(int i=0;i<file_name.length;i++) {out.print("<BR>"+file_name[i]); } %> <P>请输入一个jsp文件的名字,加载这个jsp文件: <FORM action="Example2_17.jsp" method=post name=form> <INPUT type="text" name="ok"> <BR> <INPUT TYPE="submit" value="送出" name=submit> </FORM>
<% String fileName="/Myfile/"; fileName=fileName+request.getParameter("ok"); %> <P>加载的效果: <jsp:include page="<%= fileName %>" > </jsp:include> </BODY> param标签以“名字—值”对的形式为其它标签提供附加信息,这个标签与jsp:include、jsp:forward、jsp:plugin标签一起使用。 param动作标签:
<jsp:param name= “名字” value= “指定给param的值”> 当该标签与jsp:include标签一起使用时,可以将param标签中的值传递到include指令要加载的文件中去,因此include动作标签如果结合param标签,可以在加载文件的过程中向该文件提供信息。下面例子18动态包含文件:tom.jsp,当该文件被加载时获取param标签中computer的值(获取computer的值由JSP的内置对象request调用getParameter方法完成)。 tom.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <% String str=request.getParameter("computer"); //获取值。 int n=Integer.parseInt(str); int sum=0; for(int i=1;i<=n;i++) { sum=sum+i; } %> <P> 从1到<%=n%>的连续和是: <BR> <%=sum%> </BODY> </HTML> 例子18(效果如图2.15所示) Example2_18.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <P>加载文件效果: <jsp:include page="tom.jsp"> <jsp:param name="computer" value="300" /> </jsp:include> </BODY> </HTML> forwar指令:
<jsp:forward page="要转向的页面" > </jsp:forward> 或 <jsp:forward page="要转向的页面" />
该指令的作用是:从该指令处停止当前页面的继续执行,而转向其它的一个JSP页面。 假设Example2_11.jsp存放在d:/Tomcat/Jakarta-tomcat-4.0/webapps/root/Myfile下;Example2_2存放在d:/Tomcat/Jakarta-tomcat-4.0/webapps/root/下。下面的Example2_19.jsp存放在d:/Tomcat/Jakarta-tomcat-4.0/webapps/root/下。 在下面的JSP页面中,首先随机获取一个数,如果该数大于0.5就转向页面:Example2_11.jsp;否则转向页面:Example2_2.jsp。下图2.16是Example2_19.jsp运行几次后,随机出现的两种运行效果。 例子19(效果如图2.16所示) Example2_19.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <% double i=Math.random(); if(i>0.5) { %> <jsp:forward page="/Myfile/Example2_11.jsp" > </jsp:forward> <% } else { %> <jsp:forward page="Example2_2.jsp" > </jsp:forward> <% } %> <P> 这句话和下面的表达式的值能输出吗? <%=i%> </BODY> </HTML> 该指令也可以结合param指令,向要转到的页面传送信息。下面的Example2_20.jsp页面转到come.jsp,并向转到的come.jsp页面传递一个数值,如图2.17所示。
come.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY bgcolor=cyan><FONT Size=1> <%String str=request.getParameter("number"); double n=Double.parseDouble(str); %> <P>您传过来的数值是:<BR> <%=n%> </BODY> </HTML> 例子20(效果如图2.17所示) Example2_20.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <% double i=Math.random(); %> <jsp:forward page="come.jsp" > <jsp:param name="number" value="<%=i%>" /> </jsp:forward> </BODY> </HTML> 在页面中使用普通的HTML标记<apple ….></apple>可以让客户下载运行一个java applet小应用程序,但并不是所有的客户的浏览器都支持java apple小程序,如果你的小应用程序使用了 JDK1.2以后的类,那么,目前的IE5.5并不支持这个Java小应用程序。而使用plugin动作标签可以保证客户能执行你的小应用程序。 该动作标签指示JSP页面加载java plugin,该插件由客户负责下载,并使用该插件来运行Java applet。 Plugin 动作标签:
<jsp:plugin type="applet" code="小应用程序的字节码文件" jreversion="java虚拟机版本号" width="小程序宽度值" height="小程序高度值" > <jsp:fallback> 提示信息:用来提示用户的浏览器是否支持插件下载 </jsp:fallback> </jsp:plugin>
假设有一个java applet小程序,主类字节码文件是:B.class,该文件存放在Root下。 含有plugin标签的JSP文件Example2_21.jsp也存放在Root下。
例子21 Example2_21.jsp: <%@ page contentType="text/html;charset=GB2312" %> <HTML> <BODY> <jsp:plugin type="applet" code="B.class" jreversion="1.2" width="200" height="260" > <jsp:fallback> Plugin tag OBJECT or EMBED not supported by browser. </jsp:fallback> </jsp:plugin> </body></html>
选择“是”,再选择同意下载,出现下载插件的界面,如图2.19所示。
上面JSP页面中包含的java小应用程序是完全用java swing编写的,使用表格JTable组件技术,来计算2阶行列式的小程序。如果不使用插件标签,目前的浏览器,比如IE5.5,都无法运行。以下是java applet 小应用程序的源代码:B.java,该代码摘自《Java 2 实用教程》 清华大学出版社(耿祥义等编写)。 B.java: import javax.swing.*;import java.awt.*; import java.awt.event.*; public class B extends JApplet implements ActionListener { JTable table;Object a[][]; JPanel p1,p2; Object name[]={"第1列","第2列"}; JButton button;JTextField text; public void init() { a=new Object[2][2]; button=new JButton("确定");text=new JTextField(8); p1=new JPanel();p2=new JPanel(); p1.setLayout(new GridLayout(2,1)); p1.add(new Label("输入2阶行列式的元素")); p1.add(new Label("输入或修改数据后,用鼠标点击每个格,使数据生效")); p2.add(button); p2.add(new JLabel("结果:")); p2.add(text); table=new JTable(a,name); button.addActionListener(this); getContentPane().add(new JScrollPane(table),BorderLayout.CENTER); getContentPane().add(p1,BorderLayout.NORTH); getContentPane().add(p2,BorderLayout.SOUTH); } public void actionPerformed(ActionEvent e) {if(e.getSource()==button) { double d[][]=new double[2][2]; double result; for(int i=0;i<2;i++) {for(int j=0;j<2;j++) {d[i][j]=Double.valueOf(a[i][j].toString()).doubleValue(); } } result=d[1][1]*d[0][0]-d[0][1]*d[1][0]; text.setText(String.valueOf(result)); } } } 注:如果JSP页面和java applet小程序不在同一文件下,plugin标签中应增加codebase选项,指出小程序所在的位置。比如,如果上述例子的B.class存放在Root的Myfile文件下。那么,Plugin标签:
<jsp:plugin type="applet" code="B.class" codebase="/Myfile" jreversion="1.2" width="300" height="260" > <jsp:fallback> Plugin tag OBJECT or EMBED not supported by browser. </jsp:fallback> </jsp:plugin>
注:另外,在plugin标签中还可以增加如下的选项,以便控制java applet的位置aligin:取值是“bottom”、“top”、“middle”、“left”或“right”。例如,Aligin取值是“left”时,小程序在页面的左面,页面的其它部分在右面。Hspace:指定java applet与左右对象,比如文字图象等之间的距离。Vspace:指定java applet与上下对象,比如文字图象等之间的距离。 比如:
<jsp:plugin type="applet" code="B.class" jreversion="1.2" width="300" height="260" align="left" vspace="60" > <jsp:fallback> Plugin tag OBJECT or EMBED not supported by browser. </jsp:fallback> </jsp:plugin> 该标签用来创建并使用一个java beans,是非常重要的一个动作标签,我们将在第6 章详细讨论。Sun公司的倡导是:用HTML完成JSP页面的静态部分,用javabeans完成动态部分,实现真正意义上的静态和动态分割。
|