目录
前言
本章在webapps目录下新建一个web服务目录ch2,在ch2目录下建立一个名字是image的目录,用于存放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 表达式由服务器负责计算,并将结果转化为字符串,然后交给客户的浏览器
负责显示。
2.2声明变量和定义方法
在“<%!”和“%>”标记符号之间声明变量和方法。
2.2.1 声明变量
在“<%!”和“%>”标记符之间声明变量,即在“<%!”和“%>”之间放置 Java的变量声明语句,变量的类型可以是 Java 语言允许的任何数据类型,我们将这些变量称为 JSP 页面的成员变量。“<%!”和“%>”之间声明的变量在整个 JSP 页面内都有效,因为 JSP 引擎将 JSP页面转译成 Java 文件时,将这些变量作为类的成员变量。这些变量的内存空间直到服务器关闭才释放。当多个客户请求一个 JSP 页面时,JSP 引擎为每个客户启动一个线程,这些线程由JSP 引擎服务器来管理,这些线程共享 JSP 页面的成员变量,因此任何一个用户对 JSP 页面成员变量操作的结果,都会影响到其他用户。下面的例子 2 利用成员变量被所有用户共享这一性质,实现了一个简单的计数器。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body bgcolor="yellow">
<%! int i=0; %>
<% i++;%>
<p style="font-family: 黑体;font-size: 36px">
你是第<%= i %>个访问本站的用户
</p>
</body>
</html>
2.22 定义方法和类
可以在“<%!”和“%>”标记符号之间定义方法,可以在Java程序片中调用该方法。方法内声明的变量只在该方法内有效,当方法被调用时,方法内声明的变量被分配内存,方法被调用完毕即可释放这些变量所占的内存。
2.3Java程序片
可以在“<%”和“%>”之间插入 Java 程序片。一个 JSP 页面可以有许多程序片,这些程序片将被 JSP 引擎按顺序执行。在一个程序片中声明的变量称做 JSP 页面的局部变量,它们在 JSP 页面内的所有程序片部分以及表达式部分内都有效。这是因为 JSP 引擎将 JSP 页面转译成 Java 文件时,将各个程序片的这些变量作为类中某个方法的变量,即局部变量。利用程序片的这个性质,有时候可以将一个程序片分割成几个更小的程序片,然后在这些小的程序片之间再插入 JSP 页面的一些其它标记元素。当程序片被调用执行时,这些变量被分配内存空间,所有的程序片调用完毕,这些变量即可释放所占的内存。当多个客户请求一个 JSP 页面时,JSP 引擎为每个客户启动一个线程,一个客户的局部变量和另一个客户的局部变量被分配不同的内存空间。因此,一个客户对 JSP 页面局部变量操作的结果,不会影响到其它客户的这个局部变量。
一个JSP页面中的Java程序片会按照其在页面中的顺序被执行,而且某个Java程序片中声明的局部变量在其后继的所有Java程序片以及表达式部分内都有效。利用Java程序片的这个性质,有时候我们可以把一个Java程序片分割成几个Java程序片,然后在这些Java程序片之间再插入其他标记元素。
HTML中的标记
<%
Java程序片
%>
HTML中的标记
<%
Java程序片
%>
HTML中的标记
2.4Java表达式
可以在“<%=”和“%>”之间插入一个表达式(注意:不可插入语句,“<%=”是一个完整的符号,“<%”和“=”之间不要有空格),这个表达式必须能求值。表达式的值由服务器负责计算,并将计算结果用字符串形式发送到客户端显示。
下面举个例子
<%@ page contentType = "text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=pink>
<% int x=12,y=9;
%>
<p style="font-family:宋体;font-size:36">
计算表达式x+y+x%y,即<%= x %>+<%= y %>+<%= x %>%<%= y %>的值:
<%= x+y+x%y %>
<br>计算表达式x>y即<%= x %> > <%= y %>的值:
<%= x>y %>
<br>计算表达式sin(<%= Math.PI %>/2)的值:
<%= Math.sin(Math.PI/2) %>
<br>
<% if(x-y>=0) {
%>
如果<%= x %>大于<%= y %>,计算<%= x %> - <%= y %>即
<%= x-y %>的平方根:
<%=Math.sqrt(x-y)%>
<% }
%>
</p></body></HTML>
运行结果如下:
2.5 JSP中的注释
灵活使用注释可以增强JSP页面的可读性,使JSp页面易于维护。JSP页面中的注释可分为两种
(1)HTML注释:在标记符号<! - - - >之间加入注释内容:
<! - 注释内容 - - >
JSP引擎把HTML注释交给用户,因此用户通过浏览器查看JSP页面的源文件时,能够看到HTML注释。
(2)JSP注释:在标记符号<% - - - - %>之间加入注释内容:
<% - - 注释内容 - - %>
Tomcat服务器忽略了JSP注释,即在编译JSP页面时忽略了JSP注释。
2.6 JSP指令标记
2.6.1 page指令标记
page指令用来定义整个JSP页面的一些属性和这些属性的值,属性用单引号<' '>或双引号<" ">括起来。可以使用多个page指令分别为每个属性指定值,如:
<%@page属性1 = "属性1的值" %>
<%@page属性2 = "属性2的值" %>
...
<%@page属性n = "属性n的值" %>
也可以用一个page指令同时指定多个属性的值,如:
<%@page属性1 = "属性1的值" 属性2 = "属性2的值" ... 属性n = "属性n的值"%>
例如,我们经常会在JSP页面首端编写的两个指令:
<%@page contentType = "text/html" %>
<%@page pageEncoding = "utf-8" %>
也可以合并成一个page指令,如:
<%@page contentType = "text/html" pageEncoding = "utf-8" %>
page指令的作用对整个JSP页面有效,与其书写的位置无关。习惯上把page指令写在JSP页面的最前面。
page指令标记可以为contentType、import、language、session、buffer、autoFlushis、ThreadSafe、pageEncoding、inform等属性指令值。以下将分别讲述这些属性的设置与作用。
2.6.2 include指令标记
如果需要在JSP页面內某处整体嵌入一个文件,就可以考虑使用include指令标记,其语法格式如下:
<%@include file = "文件的URL" %>
include指令标记的作用是在JSP页面出现该指令的位置处,静态嵌入一个文件,该文件的编码必须和当前JSP页面一致。被嵌入的文件必须是可以访问或可以使用的。如果该文件和当前JSP页面在同一Web服务目录中,那么“文件的URL”就是文件的名字,如果该文件在JSP页面所在的Web服务目录的一个子目录中,比如fileDir子目录中,那么文件的URL就是”fileDir/文件的名字“。所谓静态嵌入,就是当前JSP页面和嵌入的文件合并成一个新的JSP页面,然后Tomcat服务器再将这个新的JSP页面转译成JAVA文件。因此嵌入文件后,必须保证新合并成的JSP页面符合JSP语法规则,即能够成为一个JSP页面文件。比如,被嵌入的文件是一个JSP页面,该JSP页面使用page指令为contentType属性设置了值:
<%@page contentType = "application/msword" %>
那么,合并后的JSP页面就两次使用page指令为contentType属性设置了不同的属性值,导致出现语法错误。因为JSP页面中的page指令只能为contentType指定一个值。
2.7 JSP动作标记
2.7.1 include动作标记
nclude动作标记语法格式为:
<jsp : include page = "文件的URL"/>
或
<jsp : include page = "文件的URL"/>
param子标记
</jsp:include>
需要注意的是,当include动作标记不需要param子标记时,必须使用第一种形式
include动作标记告诉JSP页面动态包含一个文件,即JSP页面运行时才将文件加入。与静态嵌入文件的include指令标记不同,当Tomcat服务器根绝JSP页面产生成JAVA文件时,不把JSP页面中动作指令include所包含的文件与原JSP页面合并为一个新的JSP页面,而是告诉JAVA解释器,这个文件在JSP运行时才包含进来。
尽管include动作标记和include指令标记的作用都是处理所需要的文件,但是处理方式和处理事件是不同的。include指令标记是在编译阶段就处理所需要的文件,被处理的文件在逻辑和语法上依赖于当前的JSP页面,其优点是页面的执行速度快;而include动作标记实在JSP页面运行时才处理文件,被处理的文件在逻辑和语法上独立于当前JSP页面,其优点是可以使用param子标记更灵活的处理所需要的文件,缺点是执行速度相对慢一些。
2.7.2 param动作标记
param标记以“名字-值”对的形式为其他表及提供附加信息,param标记不能独立使用,须作为jsp:include、jsp:forward标记的子标记来使用。
param动作标记语法格式是:
<jsp:param name = "参数" value = "参数的值"/>
当该标记与jsp:include动作标记一起使用时,可以将poaram标记中参数的值传递到include动作标记要加载的文件中去,被加载的JSP文件可以使用Tomcat服务器提供的request内置对象获取include动作标记的param子标记中name给出的参数的值。因此include动作标记通过使用param子标记来处理加载的文件,比include指令标记更为灵活。
下面例子中,使用include 动作标记加载JSP文件 triangle.jsp,triangle.jsp页面保存在当前Web服务目录ch2的子目录myfile中。triangle.jsp页面可以计算并显示三角形的面积,当triangle.jsp被加载时获取example2_11.jsp 页面 include 动作标记的param子标记提供的三角形三边的长度。效果如图所示。
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=cyan >
<% double a=6.12,b=7.08,c=9.22;
%>
<p style="font-family:宋体;font-size:36">
<br>加载triangle.jsp计算三边为<%=a%>,<%=b%>,<%=c%>的三角形面积.
<jsp:include page="myfile/triangle.jsp">
<jsp:param name="sideA" value="<%=a%>"/>
<jsp:param name="sideB" value="<%=b%>"/>
<jsp:param name="sideC" value="<%=c%>"/>
</jsp:include>
</p></body></HTML>
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<%! public String getArea(double a,double b,double c) {
if(a+b>c&&a+c>b&&c+b>a) {
double p=(a+b+c)/2.0;
double area=Math.sqrt(p*(p-a)*(p-b)*(p-c)) ;
String result = String.format("%.2f",area);//保留两位小数
return result;
}
else {
return(""+a+","+b+","+c+"不能构成一个三角形,无法计算面积");
}
}
%>
<% String sideA=request.getParameter("sideA");
String sideB=request.getParameter("sideB");
String sideC=request.getParameter("sideC");
double a=Double.parseDouble(sideA);
double b=Double.parseDouble(sideB);
double c=Double.parseDouble(sideC);
%>
<p style="font-family:黑体;font-size:36;color:blue">
<br><b>我是被加载的文件,负责计算三角形的面积<br>
给我传递的三边是:<%=sideA%>,<%=sideB%>,<%=sideC%></b>
<br><b><i>三角形的面积(保留2位小数):<%= getArea(a,b,c)%></i></b></i>
</p>
运行结果如下:
2.7.3 forward动作标记
forward动作标记的语法格式是:
<jsp:forward page="要转向的页面"/>
或
<jsp:forward page = "要转向的页面"/>
param子标记
</jsp:forward>
该指令的作用是:从该指令处停止当前页面的执行,而转向执行page属性指定的JSP页面。需要注意的是,当forward动作标记不需要param子标记时,必须使用第一种形式。
forward标记可以使用param动作标记作为子标记,而转向的页面传送信息。forward动作标记指定的要转向的JSP文件可以使用Tomcat服务器提供的request内置对象获取param子标记中name指定的属性值。
需要注意的是,当前页面使用forward动作标记转向后,尽管用户看到了转向后的页面的效果,但浏览器地址栏中显示的仍然是转向前的JSP页面的URL地址,因此,如果刷新浏览器的显示,将再次执行当前浏览器地址栏中显示的JSP页面。
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body>
<h1> 产生一个1-10之间的随机数
<% double i=(int)(Math.random()*10)+1;
if(i<=5) {
%> <jsp:forward page="a.jsp" >
<jsp:param name="number" value="<%= i %>" />
</jsp:forward>
<% }
else {
%> <jsp:forward page="b.jsp" >
<jsp:param name="number" value="<%= i %>" />
</jsp:forward>
<% }
%>
</body></HTML>
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=cyan>
<p style="font-family:宋体;font-size:36">
<% String s=request.getParameter("number");
out.println("传递过来的值是"+s);
%>
<br><img src=image/pic_a.jpg width=300 height=280/>
</p></body></HTML>
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=yellow>
<p style="font-family:宋体;font-size:36">
<% String s=request.getParameter("number");
out.println("传递过来的值是"+s);
%>
<br><img src=image/pic_b.jpg width=300 height=280 />
</p></body></HTML>
结果如下:
2.7.4 useBean 动作标记
将在第5章详细讨论useBean标记。useBean 标记用来创建并使用一个JavaBean是非常重要的一个动作标记。
总结
以上为第二章的全部内容。