一、声明变量

    在"<%!""%>"标记符之间声明变量,在"<%!""%>"之间放置 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指令标记可以指定如下属性的值:
contentTypeimportlanguagesessionbufferauotFlushisThreadSafe
以下将分别讲述上述属性值的设置与作用。

  1. contentType属性
    我们已经知道,当用户请求一个JSP页面时,Tomcat服务器负责解释执行 JSP页面,并将某些信息发送到用户的浏览器,以便用户浏览这些信息。Tomcat服务器同时负责通知用户的浏览器使用怎样的方法处理接收到信息。这就要求JSP页面必须设置响应的MIMEMultipurpose 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/htmltext/plainimage/gifimage/x-xbitmapimage/jpegimage/pjpegapplication/x-shockwave-flashapplication/ nd.ms-powerpointapplication/vnd.ms-excelapplication/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);
	%>
  1. language属性
    language属性定义JSP页面使用的脚本语言,该属性的值目前只能取“java”。
    language属性指定值的格式是:
<@page language="java”%>

language属性的默认值是“java”,即如果在JSP页面中没有使用page指令指定该属性值的,那么,JSP页面默认有如下的page指令:<%@page language="java”*>

  1. 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.*;
  1. session属性
    session属性用于设置是否需要使用内置session对象。session的属性值可以是truefalsesession属性默认的属性值是true
  2. buffer属性
    内置输出流对象out负责将服务器的某些信息或运行结果发送到用户端显示。buffer属性用来指定out设置的缓冲区大小不使用缓冲区。例如:
<%@page buffer="24KB"%>

buffer属性的默认值是8KBbuffer属性可以取值”none”,即设置out不使用缓冲区
6. autoFlush属性
autoFlush属性指定out的缓冲区被填满时,缓冲区是否自动刷新autoFlush 可以取值truefalseautoFlush属性的默认值是true。当autoFlush属性取值false时,如果out的缓冲区填满,就会出现缓存溢出异常。当buffer的值是“none”时,autoFlush的值就不能设置成false
7. isThreadSafe属性
isThreadSafe属性用来设置JSP页面是否多线程访问isThreadSafe的属性值可取truefalse。当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:includejsp:forwardjsp: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="作用范围">