一、声明变量
在"<%!"
和"%>"
标记符之间声明变量,在"<%!"
和"%>"
之间放置 Java的变量声明语句。变量的类型可以是Java语言允许的任何数据类型,将这些变量称为JSP页面的成员变量。例如:
<%! int a,b = 10, c;
String tom = null,jerry = "love JSP";
Date date;
%>
在"<%!"
和"%>"
之间声明的变量在整个JSP页面内都有效,与"<%!"
和"%>"
标记符在JSP页面中的书写位置无关,但习惯上把"<%!"
和"%>"
标记符号写在JSP页面的前面。JSP引擎将JSP页面转译成Java文件时,将"<%!"
和"%>"
标记之间声明的变量作为类的成员变量。这些变量占有的内存空间直到JSP引擎关闭才释放。当多个用户请求一个JSP页面时,JSP引擎为每个用户启动一个线程,这些线程由JSP引擎来管理,这些线程共享 JSP页面的成员变量,因此任何一个用户对JSP页面成员变量操作的结果,都会影响其他页面。
<%@page contentType="text/htm1; charset=UTF-8"%>
<html>
<body bgcolor=yellow><font size=3>
<%!inti=0;
%>
<%i++;
%>
<p>您是第<%=i%>
个访问本站的用户。
</body>
</html>
二、定义方法
在"<%!"
和"%>"
标记符之间定义方法,所定义的方法在整个JSP页面有效,可以在Java程序片中被调用。方法内声明的变量只在该方法内有效,当方法被调用时,方法内的变量被分配内存。方法被调用完毕即可释放这些变量所占的内存。
实例:
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<body bgcolor=# FFAAEE>
<%! double multi(doublex, double y){
returnx*y; double div(double x, double y){
return x/y;
%>
<% doublex=3.56; doubley=18;
out.print1n(”调用multi方法计算”+x+”与”+y+"之积:<br>");
out.print1n(multi(x,y));
out.print1n("<br>调用div方法计算”+y+”除以”+x+”的商:<br>");
String s=String.format("小数点保留3位:%10.3f",div(y,x));
out.print1n(s);
%>
</body>
</html>
三、Java程序片
可以在"<%!"
和"%>"
之间插入Java程序片。一个JSP页面可以有许多程序片,这些程序片将被JSP引擎按顺序执行。在程序片中声明的变量称作JSP页面的局部变量。局部变量的有效范围与其声明的位置有关,即局部变量在JSP页面后继的所有程序片以及表达式部分内都有效。JSP引擎将JSP页面转译成Java文件时,将各个程序片的这些变量作为类中某个方法的变量,即局部变量。
当多个用户请求一个JSP页面时,JSP引擎为每个用户启动一个线程,该线程负责执行字节码文件响应用户的请求。JSP引擎使用多线程来处理程序片,特点如下:
- 操作JSP页面的成员变量。Java程序片中操作的成员变量是各个线程(用户)共享的变量,任何一个线程对JSP页面成员变量操作的结果,都会影响其他线程。
- 调用JSP页面的方法。Java程序片中可以出现方法调用语句,所调用的方法必须是JSP页面曾定义的方法。
- 声明操作局部变量。当一个线程享用CPU资源时,JSP引擎让该线程执行Java程序片,这时,Java程序片中的局部变量被分配内存空间,当轮到另一个线程享用CPU资源时,JSP引擎让该线程再次执行Java程序片,那么,Java程序片中的局部变量会再次分配内存空间。也就是说Java程序片已经被执行了两次,分别运行在不同的线程中,即运行在不同的时间片内。运行在不同线程中的Java程序片的局部变量互不干扰,即一个用户改变Java程序片中的局部变量的值不会影响其他用户的Java程序片中的局部变量。当一个线程将Java程序片执行完毕,运行在该线程中的Java程序片的局部变量释放所占的内存。
注意:
根据Java程序片的上述特点,对于某些特殊情形必须给予特别注意。比如,如果一个用户在执行Java程序片时调用JSP页面的方法操作成员变量,可能不希望其他用户也调用该方法操作成员变量,以免对其产生不利的影响(成员变量被所有的用户共享),那么就应该将操作成员变量的方法用synchronized
关键字修饰。当一个线程在执行Java程序片期间调用synchronized
方法时,其他线程在其Java程序片中调用这个synchronized
方法时就必须等待,直到正在调用synchronized
方法的线程调用执行完该方法。在下面的例子中,通过synchronized
方法操作一个成员变量来实现一个简单的计数器。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%!
int count = 0; //被用户共享的count
synchronized void setCount() { //synchronized修饰的方法
count++;
}
%>
<%
setCount();
out.println("您是第" + count + "个访问本站的用户");
%>
</body>
</html>
一个JSP页面中的Java程序片会按其在页面中的顺序被执行,而且某个Java程序片中声明的局部变量=在其后继的所有Java程序片以及表达式部分内都有效。利用Java程序片的这个性质,有时可以将一个Java程序片分割成几个Java程序片,然后在这些Java程序片之间再插入其他标记元素。在程序片中插入HTML标记的技巧对于灵活显示数据是非常重要的。通常的格式是:
<%
Java程序片1
%>
HTML标记
<%
Java程序片2
%>
HTML标记
四、Java表达式
可以在“<%=”
和“%>”
之间插入一个表达式(注意:不可插入语句,“<%=
”是一个完整的符号,“<%
”和“=
”之间不要有空格),这个表达式必须能求值。表达式的值由服务器负责计算,并将计算结果用字符串形式发送到用户端显示。
注意:
在JSP页面中,表达式的值被表示成一个字符串的形式,即Tomcat引擎将表达式的结果转换成字符串,然后发送给用户的浏览器。因此,在编写JSP页面时,要把Java表达式按普通的文本来使用。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="#f0ffff"><font size="3">
<%
int x = 12, y = 9;
%>
计算表达式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)%>
<%
}
%>
</font>
</body>
</html>
五、JSP中的注释
注释可以增强JSP页面的 可读性 ,使JSP页面 易于维护。JSP页面中的注释可分为两种。
- HTML注释:在标记符号“
<!--
”和“-->
”之间加入注释内容:
<!-- 注释内容 -->
JSP引擎把HTML注释交给用户,因此用户通过浏览器查看JSP页面的源文件时,能够看到HTML注释。
- JSP注释:在标记符号“
<%--
”和“--%>
”之间加入注释内容:
<%--注释内容 --%>
JSP引擎忽略 JSP注释,即在编译 JSP页面时忽略JSP注释。
- 实例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 以下字体的颜色为蓝色 -->
<font size = 3 color = blue>
抽取字符串"C:\myfile\jspfile\example.jsp"中的"example.jsp"
</font>
<%--下面是成员变量的声明 --%>
<%!
String s = "C:\\myfile\\jspfile\\example.jsp";
%>
<%-- 下面是Java程序片 --%>
<%
int index = s.lastIndexOf("\\");
String str = s.substring(index + 1);
%><br>
<%-- 下面是Java表达式 --%>
<%= str %>
</body>
</html>
六、JSP指令标记
1、page
指令标记
page
指令用来定义整个JSP页面的一些属性和这些属性的值,属性值用单引号或双引号括起来。可以用一个page
指令指定多个属性的值
例如:
<%@page属性1=“属性1的值”属性2=“属性2的值”…%>
也可以使用多个 page指令分别为每个属性指定值,
例如:
<%@page属性1=”属性1的值”%><%@page属性2=”属性2的值”%><%@page属性n=“属性n的值”%>
page
指令的作用对整个JSP页面有效,与其书写的位置无关。习惯上把page指令写在JSP页面的最前面。
page
指令标记可以指定如下属性的值:
contentType
、import
、language
、session
、buffer
、auotFlush
、isThreadSafe
。
以下将分别讲述上述属性值的设置与作用。
contentType
属性
我们已经知道,当用户请求一个JSP页面时,Tomcat服务器负责解释执行 JSP页面,并将某些信息发送到用户的浏览器,以便用户浏览这些信息。Tomcat服务器同时负责通知用户的浏览器使用怎样的方法来处理所接收到的信息。这就要求JSP页面必须设置响应的MIME
(Multipurpose Internet Mail Extention
)类型和JSP页面字符的编码,即设置contentType
属性的值。contentType
属性值确定JSP页面响应的MIME
类型和JSP页面字符的编码。属性值的一般形式是:
"MIME"类型
或
“MIME类型;charset=编码”
比如,如果我们希望用户的浏览器启用HTML解析器来解析执行所接收到的信息(即所谓的网页形式),就可以如下设置contentType
属性的值:
<@page contentType="text/html;charset=UTF-8"%>
如果希望用户的浏览器启用本地的MS-Word
应用程序来解析执行收到的信息,就可以如下设置contentType
属性的值:
<%@page contentType="application/msword"%>
如果不使用page
指令为contentType
指定一个值,那么contentType
属性的默认值是:
"text/html;charset=ISO-8859-1"
JSP页面使用page
指令只能为contentType
指定一个值,不允许两次使用 page
指令给contentType
属性指定不同的属性值,下列用法是错误的
<%@page contentType="text/html;charset =gb2312”%>
<%@page contentType="application/msword"%>
可以使用page
指令为contentType
属性指定的值有:text/html
、text/plain
、image/gif
、image/x-xbitmap
、image/jpeg
、image/pjpeg
、application/x-shockwave-flash
、application/ nd.ms-powerpoint
、application/vnd.ms-excel
、application/msword
等。
如果用户的浏览器不支持某种MIME类型,那么用户的浏览器就无法用相应的手段处
理所接收到的信息。比如,使用page
指令设置 contentType
属性的值是application/ msword
,如果用户浏览器所驻留的计算机没有安装MS-Word
应用程序,那么浏览器就无法处理所接收到的信息。
<%@ page language="java" contentType="image/x-xbitmap; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.awt.*" %>
<%@ page import="java.io.*" %>
<%@ page import="java.awt.image.*" %>
<%@ page import="java.awt.geom.*" %>
<%@ page import="com.sun.image.codec.jpeg" %>
<% int width = 260,height = 260;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(Color.white);
g.fillRect(0,0,width,height);
Graphics2D g_2d = (Graphics2D)g;
Ellipse2D ellipse = new Ellips2d.Double(40,50,100,40);
g_2d.setColor(Color.blue);
g_2d.draw(ellipse);
Polygon polygon = new Polygon();
polygon.addPoint(12,34);
polygon.addPoint(51,134);
polygon.addPoint(102,34);
g_2d.drawPolygon(polygon);
g_2d.dispose();
OutputStream outClient = response.getOutputStream(); //获取指向用户端的输出流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEnconder(outClient);
encoder.enconde(image);
%>
language
属性
language
属性定义JSP页面使用的脚本语言,该属性的值目前只能取“java
”。
为language
属性指定值的格式是:
<@page language="java”%>
language
属性的默认值是“java
”,即如果在JSP页面中没有使用page
指令指定该属性值的,那么,JSP页面默认有如下的page
指令:<%@page language="java”*>
import
属性
该属性的作用是为JSP页面引入Java运行环境提供的包中的类,这样就可以在JSP页面的程序片部分、变量及方法定义部分以及表达式部分使用包中的类。可以为该属性指定多个值,该属性的值可以是某包中的所有类或一个具体的类,例如:
<%@page import="java.io.*","java.util.Date”%>
JSP页面默认import
属性已经有如下的值:
“java.lang.*
”、"javax.servlet.*
"、"javax.servlet.jsp.*
"、"javax.servlet.http.*
".
当为import
指定多个属性值时,例如:
<%@page import="java.util.*”%>
<%@page import="java.io.*”%>
那么,JSP引擎把JSP页面转译成的Java文件中会有如下的import
语句:
import java.util.*;import java.io.*;
session
属性
session
属性用于设置是否需要使用内置的session
对象。session
的属性值可以是true
或false
。session
属性默认的属性值是true
。buffer
属性
内置输出流对象out
负责将服务器的某些信息或运行结果发送到用户端显示。buffer
属性用来指定out
设置的缓冲区的大小或不使用缓冲区。例如:
<%@page buffer="24KB"%>
buffer
属性的默认值是8KB
。buffer
属性可以取值”none
”,即设置out
不使用缓冲区。
6. autoFlush
属性
autoFlush
属性指定out
的缓冲区被填满时,缓冲区是否自动刷新。autoFlush
可以取值true
或false
。autoFlush
属性的默认值是true
。当autoFlush
属性取值false
时,如果out
的缓冲区填满,就会出现缓存溢出异常。当buffer
的值是“none
”时,autoFlush
的值就不能设置成false
。
7. isThreadSafe
属性
isThreadSafe
属性用来设置JSP页面是否可多线程访问。isThreadSafe
的属性值可取true
或false
。当isThreadSafe
属性值设置为true
时,JSP页面能同时响应多个用户的请求;当isThreadSafe
属性值设置成false
时,JSP页面同一时刻只能响应一个用户的请求,其他用户须排队等待。is ThreadSafe
属性的默认值是true
。
当isThreadSafe
属性值为true
时,CPU的使用权在各个线程间快速切换。也就是说,即使一个用户的线程没有执行完毕,CPU的使用权也可能要切换给其他的线程,如此轮流,直到各个线程执行完毕;当JSP使用page
指令将isThreadSafe
属性值设置成false
时,该JSP页面同一时刻只能响应一个用户的请求,其他用户须排队等待。也就是说,CUP要保证一个线程将JSP页面执行完毕才会把CPU使用权切换给其他线程。
8. info
属性
info
属性的属性值是一个字符串,其目的是为JSP页面准备一个常用但可能要经常修改的字符串。例如:
<%@page info="we are students"%>
可以在JSP页面中使用方法:getServletInfo();
获取info
属性的属性值。
2、include
指令标记
如果需要在JSP页面内某处整体嵌入一个文件,就可以考虑使用include
指令标记,其语法格式如下:
<%@include file=“文件的URL”%>
include
指令标记的作用是在JSP页面出现该指令的位置处,静态插入一个文件。被插入的文件必须是可以访问或可以使用的。如果该文件和当前JSP页面在同一Web服务目录中,那么”文件的URL”就是文件的名字;如果该文件在JSP页面所在的Web服务目录的一个子目录中,比如fileDir子目录中,那么”文件的URL“就是“fileDir/文件的名字
”。所谓静态插入,就是当前JSP页面和插入的文件合并成一个新的JSP页面,然后JSP引擎再将这个新的JSP页面转译成Java文件。因此,插入文件后,必须保证新合并成的JSP页面符合JSP语法规则,即能够成为一个JSP页面文件。比如,被插入的文件是一个JSP页面,该JSP页面使用page
指令为contentType
属性设置的值:
<%@page contentType="application/msword"%>
那么,合并后的JSP页面就两次使用page
指令为contentType
属性设置了不同的属性值,导致出现语法错误。因为JSP页面中的page
指令只能为contentType
指定一个值。
使用include
指令可以实现代码的复用。比如,每个JSP页面上可能都需要一个导航条,以便用户在各个JSP页面之间方便地切换,那么每个JSP页面都可以使用include
指令在页面的适当位置整体嵌入一个相同的文件。
七、JSP动作标记
1、include
动作标记
include
动作标记语法格式为:
<jsp:include page=“文件的URL"/>
或
<jsp:include page=”文件的URL">
param子标记
</jsp:include>
需要注意的是,当include
动作标记不需要param
子标记时,必须使用第一种形式。include
动作标记告诉JSP页面动态包含一个文件,即JSP页面运行时才将文件加入。
与静态插入文件的include
指令标记不同,当JSP引擎把JSP页面转译成Java文件时,不把JSP页面中动作指令include
所包含的文件与原JSP页面合并为一个新的JSP页面,而是告诉Java解释器,这个文件在JSP运行(Java文件的字节码文件被加载执行)时才包含进来。
如果包含的文件是普通的文本文件,就将文件的内容发送到用户端,由用户端的浏览器负责显示;如果包含的文件是JSP文件,JSP引擎就执行这个文件,然后将执行的结果发送到用户端,并由用户端的浏览器负责显示这些结果。
尽管include
动作标记和include
指令标记的作用都是处理所需要的文件,但是处理方式和处理时间是不同的。include
指令标记是在编译阶段就处理所需要的文件,被处理的文件在逻辑和语法上依赖于当前的JSP页面,其优点是页面的执行速度快;而include
动作标记是在JSP页面运行时才处理文件,被处理的文件在逻辑和语法上独立于当前JSP页面,其优点是可以使用param
子标记更灵活地处理所需要的文件(见后面的param动作标记_,缺点是执行速度要慢一些。
注意:书写include
动作标记<jsp:include page…/>
时要注意:“jsp
”、“:
”、“include
”三者之间不要有空格。
2、param
动作标记
param
标记以“名字一值”对的形式为其他标记提供附加信息,param
标记不能独立使用,需作为jsp:include
、jsp:forward
、jsp:plugin
标记的子标记来使用。param
动作标记语法格式是:
<jsp:paran name="名字”value="指定给param的值”>
当该标记与jsp:include
动作标记一起使用时,可以将param
标记中的值传递到include
动作标记要加载的文件中去,被加载的JSP文件可以使用Tomcat 服务器提供的request
内置对象获取include
动作标记的param
子标记中name
属性所提供的值,include
动作标记通过使用param
子标记来处理加载的文件,比include
指令标记更为灵活。
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页面。
4、useBean
动作标记
Sun公司倡导的是:Javabean负责存储数据,JSP页面显示Javabean中的数据,而servlet负责管理Javabean中的数据。
作用:在jsp页面中实例化或者在指定范围内使用javabean
:
<jsp:useBean id="标示符" class="java类全名" scope="作用范围">