JSP(Java Server Pages)是由Sun公司倡导、多家公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件(*.jsp)。
JSP是一种实现普通静态HTML和动态部分混合编码的技术。JSP设计的目的在于简化表示层的表示。JSP并没有增加任何本质上不能用Servlet实现的功能。但是,在JSP中编写静态HTML更加方便,不必再用println语句来输出每一行HTML代码。更重要的是,借助内容和外观的分离,页面制作中不同性质的任何可以方便地分开。
当用户访问JSP页面时,JSP页面的处理过程如图所示。
(1)当客户第一次请求JSP页面时,JSP引擎会通过预处理把JSP文件中的静态数据(HTML文本)和动态数据(Java脚本)全部转换为Java代码。这个转换工作实际上是非常直观的,对于HTML文本只是简单的用out.println()方法包裹起来,对于Java脚本只是保留或做简单的处理。
(2)JSP引擎把生成的.java文件编译成Servlet类文件(.class)。对于Tomcat服务器而言,生成的类文件默认的情况下存放在<Tomcat>\work目录。
(3)编译后的class对象被加载到容器中,并根据用户的请求生成HTML格式的响应页面。
在执行JSP网页时,通常可分为两个时期:转译时期(Translation Time)和请求时期(Request Time)。在转译时期,JSP网页被转译成Servlet类,然后被编译成类文件;在请求时期,Servlet类执行后,响应结果至客户端。整个过程如图所示。
上面的代码由于没有在源文件hello.jsp的<body>标签中加入JSP元素,所以转义前和请求后的<body>中的内容是一样的,读者学习了JSP元素后,试验一下就可以看到区别了。
尽管JSP文件看起来更像是HTML文件而不是Servlet文件,但事实上它将转换为Servlet文件,其中的静态HTML仅仅用来输出Servlet服务方法返回的信息。如果JSP页面已经被转换为Servlet且该Servlet被编译进而被转载(在第一次被请求时),这样再次请求次JSP页面时,将感觉不到延迟。一些Web服务器允许为JSP文件定义别名,好像一个URL是指向一个HTML,但事实上指向的是一个Servlet或JSP页面。
构造一个JSP页面,除了可内嵌规则的HTML代码之外,还有三类主要的JSP元素:脚本元素(Scripting Element),指令(Directive)和动作(Action)。
脚本元素用来嵌入Java代码,这些Java代码将成为转换得到的Servlet的一部分;
指令用来从整体上控制Servlet的结构;
动作用来引入现有的组件来控制Web容器的行为。
此外,为了简化脚本元素,JSP定义了一组可以直接使用的隐式对象变量。
脚本元素(Scripting Element)包含三个部分:Scriptlet、Expression(表达式)和Declaration(声明)。
Scriptlet元素允许Java代码被直接嵌入到JSP页面。
Expression元素是Java语言表达式,它的值用于计算以及作为字符串返回到页面。
Declaration元素用于声明在页面中初始化的变量、方法和类。
语法:<% code %>
功能:Scriptlet中可以包含有效的程序片段,只要是合乎Java本身的标准语法即可。通常主要的程序也是写在这里,Scriptlet是以<%为开始,%>为结尾。
注意:编译JSP时,编译器在_jspService()方法中只是简单地不做修改地包含Scriptlet的内容。
Scriptlet能够包含多个语句,方法,变量,表达式,可以完成以下功能。
(1) 声明将要用到的变量或方法;
(2)显示出表达式;
(3)使用任何隐含对象和使用<jsp:useBean>声明过的对象;
(4)当JSP收到客户端的请求时,Scriptlet就好被执行,如同Servlet的doGet()和doPost()。
语法:<%=expression %>
功能:JSP提供了一种简单方法访问可用的Java变量和Java表达式,并生成页面HTML字符串。Expression元素是以<%=为开始,%>为结尾的,其中内容包含一段合法Java的表达式。
主要:
(1)表达式会被自动转化为字符串然后显示出来;
(2)<%与=之间不能有空格;
(3)表达式不能以分号结尾。
语法:<%!declaration;%>
功能:在JSP程序中声明变量、方法和类。声明是以<%!为开始,%>为结尾的。
注意:
(1)编译JSP时,scriptlet生成了_jspService()方法的一部分,而Declaration(声明)却生成于_jspService()方法之外,与源文件合为一起。使用<%! %>方式所声明的变量为全局变量,即表示若同时有n个用户在执行此JSP网页时会共享此变量。因此应尽量少用声明变量,若要使用变量时,直接在Scriptlet之中声明使用即可;
(2)每一个声明仅在一个页面中有效,如果要在每个页面都用到一些声明,最好把它们写成一个单独的JSP网页,然后用<%@include%>或<jsp:include >元素包含进来;
(3)<%与!之间不能有空格;
(4)Declaration元素必须是完整的Java语句,以分号结尾,和Scriptlet元素一样;
(5)Declaration元素不能产生任何输出,而Scriptlet和Expression元素可以产生输出。
JSP指令负责发送消息到JSP引擎,不包含业务逻辑,不修改out流,只是告诉JSP引擎JSP页面应该如何编译。JSP指令的作用范围仅限于包含指令本身的JSP页面。
JSP指令的语法如下:
<%@directive attribute="attribute value"%>
JSP指令可有三种类型:page指令、include指令和taglib指令。
page指令定义了一些属性,通知关于JSP页面一般设置的Servlet引擎的属性。page指令可以指出的属性在下表中列出。
属性 | 定义 |
language=”ScriptLanguage” |
指定JSP Container用什么语言来编译,目前只支持JAVA语言。默认为JAVA |
extends=”className” |
定义此JSP网页产生的Servlet是继承哪个 |
import=”importList” |
定义此JSP网页要使用哪些Java API |
session=”true|false” |
决定此页面是否使用session对象。默认为true |
buffer=”none|size in kb” |
决定输出流(Input stream)是否又缓冲区。默认为8kb |
autoFlush=”true|false” |
决定输出流的缓冲区慢了后是否需要自动清除,缓冲区慢了后会产生异常错误(Exception).默认为true |
isThreadSafe=”true|false” |
是否支持线程。默认为true |
errorPage=”url” |
如果此页发生异常,网页会重新指向一个url |
isErrorPage=”true|false” |
表示此页面是否为错误处理页面。默认为false |
contentType=”text/html;charset=gb2312” |
表示MIME类型和JSP的编码方式。笔者使用例左 |
pageEncoding=”ISO-8859-1” |
编码方式。(笔者已经加入使用的编码) |
isELLgnored=”true|false” |
表示是否在此JSP页面中EL表达式。true则忽略,反之false则支持。默认为false |
page指令是针对当前页面的指令,常用的page指令有8个:
1.<%@page language="java"%>设置jsp中用到的语言,用到的是java,也是目前唯一有效的设定
2.<%@page extends="mypackage.myclass"%>设置目前jsp要继承的父类,一般不需要设置,在默认情况下,jsp页面默认的父类是HttpJspBase。
3.<%@page import="java.sql.*"% > jsp页面所用到的类
4.<%@page errorPage="error.jsp"%> 设置该jsp页面出现异常时所要转到的页面,如果没设定,容器将使用当前的页面显示错误信息
5.<%@page isErrorPage="true"%> 设置该jsp页面是否作为错误显示页面,默认是false,如果设置为true,容器则会在当前页面生成一个exception对象,和4拍配使用
6.<%@page contentType="text/html;charset=gb2312"%> 设置页面文件格式和编码方式
7.<%@page isThreadSafe="true"% > 设置容器以多线程还是单线程运行该jsp页面,默认是true,是多线程。设置为false,则以单线程的方式运行该jsp页面
8.<%@page session="true"% > 设置该jsp页面是否可以用到session对象(jsp内置对象,为web容器创建),默认是true,能用到session.设置为false,则用不到
最后,对于page指令,还有几点需要注意:
1.<%@page %>指令作用于整个JSP页面,同样包含静态的包含文件。但是<%@page%>指令不能作用于动态的包含文件。
2.可以再一个页面中引用多个<%@page %>指令,但是除了import属性能多次使用之外,其他的属性都只能用一次。
3.<%@page %>指令可以放在JSP文件的任何地方,但是为了JSP程序的可读性及养成好的编程习惯,最好还是放在JSP文件的顶部。
用include指令指出编译JSP页面时要插入的文件名(以相对URL形式),所以被包括的文件内容成为JSP页面的一部分。include指令也可以用来插入为多页面所公用的部分代码,以避免对每个代码实例单独使用bean。
注意:
通过include指令包含的文件是由JSP分析的,并且这部分分析工作是在转换阶段,即在JSP被编译为Servlet是进行的。
JSP动作不同于JSP指令,它利用XML语法格式的标记来控制Servlet引擎的行为。JSP动作可以改变out流,以及创建和使用对象。遵循XML标准,JSP动作也可以有属性。有2个属性是所有JSP动作共有的:一是id属性;二是scope属性。
id属性唯一地标识JSP动作,这就允许在JSP页面内引入动作。
scope属性标识JSP动作的生命期。scope属性有4个可能的值:page、request、session、和application。
id属性和scope属性直接相关,因为scope属性决定与id相关联的对象的生命期。
JSP动作的语法如下:
<jsp:action attribute="attribute value"/>
JSP动作可以分为两类:Resource动作和JavaBean动作。
(1)<jsp:include>: 可以用于将静态和动态页面插入当前页面。
include动作的语法如下:
<jsp:include page="URL" flush="true"/>
这里的flush参数必须为true。
注意:include动作和include指令有很大的不同。include动作在执行时才对包含的文件进行处理,如果对包含的文件进行了修改,那么运行时可以看到所包含文件修改后的结果。而include指令包含的文件如果发生了变化,必须重新将JSP文件编译为Servlet文件才能看到所包含文件修改后的结果。
(2)<jsp:forward>:终止当前页面的动作并将请求转发到另一个资源。
(3)<jsp:plugin>:根据浏览器的类型,插入通过Java插件运行Java Applet所必须的OBJECT和EMBED元素。
JavaBean动作都涉及在JSP页面内使用服务器端JavaBean,包括:
<jsp:useBean>: 用于寻找或者实例化一个新的javaBean供以后在JSP页面中使用。
<jsp:setProperty>:设置JavaBean的属性。
<jsp:getProperty>:获取JavaBean的属性。