随着Internet和电子商务等应用的发展,动态网页技术诞生了。动态网页和网页上的动画根本不是一回事,它有以下几个特点:
交互性:即网页会根据用户的要求和选择而动态改变和响应。
自动更新:即无需手动更新HTML文档,自动生成新的页面,这可大大节省工作量。
因时因人而变:即当不同的时间、不同的用户访问同一网址时会产生不同的页面,这就是所谓的个性化技术。
在传统的网页HTML文件(*.htm,*.html)中加入Java程序片断(Scriptlet)和JSP标记,就构成了JSP网页(*.jsp)。
JSP技术是由Servlet技术发展来的。因为JSP在编写表示页面时远比Servlet简单,并且不需要手工编译(由容器自动编译),所以在Java服务器端编程中普遍采用的就是JSP。
JSP的优势
一次编写,到处运行:代码不用做任何更改
系统的多平台支持:基本上可在任意环境中开发
在任意环境中部署:在任意环境中扩展
强大的可伸缩性:从一台服务器到多台服务器均能游刃有余
多样化的开发工具
JSP的弱势
为了跨平台,为了伸缩性,增加了产品的复杂性;
JSP运行是用class常驻内存来完成的,虽然提高了响应速度,但要占用相当内存。
JSP文件的构成元素:
注释
模板元素
脚本元素
指令元素
动作元素
(1)模板元素
模板元素是指JSP的静态HTML或者XML内容.它对JSP的显示是非常必要的,但对JSP的编程人员来说,就不必关心这部分内容了,因为这部的任务主要由网页美工来完成.这些摸板元素可以说是网页的框架,它影响页面的结构和美观程度,在JSP编译时,它将把这些模板元素编译到Servlet里.当客户请求JSP时,它会把这些模板元素一字不变的发送到客户端.
(2)注释元素
1)HTML/XML注释:
<!-- comment[<%=expression%>]-->
例如:
<!--这是一个典型的JSP,它包含了JSP中常用的元素--> <!--当前时间为:<%=new.java.util.Date()%>-->
这里的注释和HTML中的注释很象,唯一不同的是可以在这个注释中使用表达式.
2)隐藏注释:
隐藏注释写在JSP程序中,但不发送给客户.
语法:<%-- comment --%>
例如:
<%-- 下面是使用表达式的例子--%>
用隐藏注释标记的字符会在JSP编译时被忽略.
3)Scriptlets中的注释:
由于Scriptlets包含的是java代码,所以java中的注释规则在scriptlets中也适用,常用的java注释使用”//”表示单行注释,使用”/** */表示多行注释.
(3)脚本元素
脚本元素包括:
声明(Declaration)
表达式(Expression)
Scriptlets
1)声明:
就是在JSP程序中声明合法的变量和方法。
2)表达式:
就是位于<%=表达式%>之间的代码。
3)Scriptlets:
就是位于<%和%>之间的,它们是合法的Java代码。
声明和Scriptlet中定义变量的区别
因为JSP页面实际上是被编译成Servlet类执行的,所以声明中定义的变量是Servlet类的成员变量Scriptlet中定义的变量是Servlet类的service()方法或doGet()方法或doPost()方法等中的局部变量
(4)指令元素
JSP中有3种指令元素,它们是:
页面(page)指令
include指令
taglib指令
1)page指令
<%@page [language=“java”] [import=“{package.class | package.*},…”] [contentType=“TYPE;charset=CHARSET”] [session=“true | false”] [buffer=“none | 8kb | sizekb”] [autoFlush=“true | false”] [isThreadSafe=“true | false”] [info=“text”] [errorPage=“relativeURL”] [isErrorPage=“true | false”] [extends=“package.class”] [isELIgnored=“true | false”] [pageEncoding=“peinfo”] %>
page指令的属性
属 性 | 描 述 | 缺省值 |
language | 定义要使用的脚本语言。如果在将来 JSP容器支持多种语言时可使用它。 | “java” |
import | 定义以逗号分隔的类或包的列表,就像在通常的 Java代码中所使用的import语句那样。 | 无 |
session | 指定这个页面是否参与一个Http会话。 | “true” |
buffer | 定义对客户端输出流的缓冲模型。如果值为“none”,则没有缓冲,直接输出。如果定义了缓冲区的尺寸,则将输出写到不小于该值的缓冲区中。 | 8KB |
autoFlush | 如果值为“true”,则当缓冲区满时,自动输出给客户; 如果值为“false”,则当缓冲区满时,会有一个运行时异常。 | “true” |
info | 关于JSP页面的信息,它是一个字符串,可用servlet.getServletInfo()获得。 | 无 |
isErrorPage | 表明该页是否为其它页的errorPage。若为true,则可以使用exception对象,若为false,则不能使用。 | “false” |
errorPage | 定义此页面出现异常时要调用的页面。 | 无 |
isThreadSafe | 用来设置JSP文件是否能多线程使用。若为true,则JSP能同时处理多个用户的请求。若为false,则JSP只能一次处理一个请求。 | “true” |
contentType | 定义JSP的字符编码方式和JSP页面响应的MIME类型。 | TYPE=text/html; CHARSET=iso-8859-1 |
method | 指定Scriptlet代码属于哪个方法。该属性的有效值包括service、doGet、doPost等。 | Method=“service” |
isELIgnored | 指定EL是否被忽略,若为true,则忽略“${}”表达式的计算。 | 由web.xml的版本确定,Servlet2.3以前的版本将忽略 |
2)include指令
该指令用于将另一个文件的内容插在JSP文件中。
一个 JSP 页面中的 include 指令的数量不受限制。
语法:<%@ include file= "filename" %>
使用include指令可以把一个复杂的JSP页面分成若干简单的部分,当要对页面更改时,只需更改对应的部分就行了。
通常情况下把页面分成多个区,典型的分区方法如下:
Jsp另一种包含文件的方法
<jsp:include page=“”/>
3)taglib指令
这个指令允许页面使用自定义标记库。
标记库是扩展 JSP 功能的自定义标记的集合。
语法:
<%@ taglib uri ="taglibURI" prefix = "tagPrefix" %>
uri告诉JSP容器如何找到标签描述文件和标签库,prefix定义引用标签时的前缀。
(4)动作元素
与指令元素不同的是,动作元素在请求处理阶段起作用,JSP规范定义了一系列的标准动作,它们都以jsp为前缀,常用的有:
<jsp:param> <jsp:params> <jsp:expression>
<jsp:include> <jsp:attribute> <jsp:plugin>
<jsp:forward> <jsp:body> <jsp:invoke>
<jsp:useBean> <jsp:text> <jsp:output>
<jsp:setProperty> <jsp:element> <jsp:doBody>
<jsp:getProperty> <jsp:scriptlet> <jsp:root>
<jsp:param>
jsp:param操作被用来以”名--值”对的形式来为其他标签提供附加信息。它与jsp:include、jsp:forward、jsp:plugin一起使用。它的使用方式如下:
<jsp:param name=“paramName” value=“paramValue”/>
其中name为属性相关联的关键字,value为属性的值。
<jsp:include>
jsp:include操作允许在请求时间内在现成的JSP页面里包含静态或动态的资源。被包含的对象只是对JSP writer对象的访问权,并且它不能设置头或者Cookie。如果页面输出是缓冲的,那么缓冲区的刷新要优先于包含的刷新。此指令在运行上效率比<%@page include%>指令的效率底,但可以动态增加内容。可以通过如下的格式 使用include指令:
<jsp:include page=“fileName” flush=“true”/>
或者:
<jsp:include page=“fileName” flush=“true”> <jsp:param name=“paramName” value=“paramValue”/> …… </jsp:include>
page=“fileName”:
参数为一个相对路径,或者是代表相对路径的表达式。如果路径以“/”开头,那么路径主要是参照JSP应用的上下关系路径。如果路径以文件名或目录名开头,那么这个路径就是正在使用的JSP文件的当前路径。
flush=“true”:
这里必须使用flush=“true” 不能使用false值。默认值为false。
<jsp:param>:
此子句能让你传递一个或多个参数给动态页面。
注意:和<%@include %>不同的是,<jsp:include>包含的内容可以是动态的,它在执行时才确定,而前者包含的内容是固定不变的,一经编译,就不能改变。
<jsp:forward>
jsp:forward操作容许将请求转发到另一个JSP、Servlet或者静态资源文件。请求被转向到的资源必须位于同JSP发送请求相同的上下文环境之中。每当遇到此操作,就停止执行当前的JSP,转而执行被转发的资源。语法:
<jsp:forward page=“uri”/>
或:
<jsp:forward page=“uri”> <jsp:param name=“paramName” value=“paramValue”/> …… </jsp:forward>
page=“uri”:
“uri”值为一个表达式或者一个字符串,它用于说明将要定向的文件或URI。
这个文件可以是一个JSP文件,也可以是程序段,或者其他能够处理request对象的文件。
<jsp:setProperty>
此操作与useBean协作,用来设置Bean的简单属性和索引属性。<jsp:setProperty>标签使用Bean给定的setXXX()方法,在Bean中设置一个或多个属性值。利用<jsp:setProperty>设置属性值有多种方法。
<jsp:setProperty name=“beanName” propertyDetails/>
其中,propertyDatails可以是下面几个中的一个:
Property=“*”
Property=“propertyName” param=“parameterName”
Property=“propertyName”
Property=“propertyName” value=“propertyValue”
1)name=“beanName”
这个是必选项。其值为Bean的名字,为在这之前用jsp:useBean引入的名称。
2)propertyDetails
Property=“*”
这是一种设置Bean属性的快捷方式。在Bean中,属性的名字、类型必须和request对象中的参数名称相匹配。由于在表单中传递过来的数据类型都是String类型的,jsp内在机制会把这些参数转化成Bean属性对应的类型。如果request对象的参数中有空值,那么对应的Bean属性将不会设置任何值。同样,如果Bean中有一个属性没有与之对应的request参数值,那么这个属性也不会设定。如果使用了property=“*”,那么Bean的属性没有必要按HTML表单中的顺序排序。
property=“propertyName”
使用request中的一个参数值指定Bean中的一个属性值。在这个语法中,property指定Bean属性名,而且Bean属性名和request参数的名字应相同,否则需要用另外一种语法,即指定param。 propertyName名字和Bean中的setXXX()中的XXX是一致的。从客户传到服务器上的参数值一般都是字符类型,这些字符串为了能够在Bean中匹配就必须转换成对应的类型。如果request对象的参数值中有空值,那么对应的Bean属性将不会设定任何值。下表列出了Bean属性的类型及它们的转换方法。
Property类型 | 方 法 |
char | java.lang.Character.valueOf(String).charValue() |
double | java.lang.Double.valueOf(String).doubleValue() |
int | java.lang.Inteter.valueOf(String).intValue() |
Integer | java.lang.Inteter.valueOf(String) |
float | java.lang.Float.valueOf(String).floatValue() |
Float | java.lang.Float.valueOf(String) |
long | java.lang.Long.valueOf(String).longValue() |
Long | java.lang.Long.valueOf(String) |
Double | java.lang.Double.valueOf(String) |
boolean | java.lang.Boolean.valueOf(String).booleanValue() |
byte | java.lang.Byte.valueOf(String).byteValue() |
property=“propertyName” param=“parameterNmae”
在Bean属性的名字和request中参数名字不同时使用这个方法。Param指定request中的参数名。如果request对象的参数值中有空值,那么对应的Bean属性将不会设置任何值。
property=“propertyName” value=“propertyValue”
Value值是可选项使用指定的值设定Bean属性。这个值可以是字符串,也可以是表达式。如果是字符串,则通过相应的对象或包的标准的valueOf方法将自动地转换为Bean属性的类型。如果是一个表达式,那么它的类型必须和它将要设定的类型一致。如果参数值为空,那么对应的属性值也不会被设定。另外,不能在一个<jsp:setProperty>中同时使用param和value.
<jsp:getProperty>
Jsp:getProperty操作是对jsp:setProperty操作的补充,它用来访问一个Bean的属性。它访问的属性值将它转化为一个String,然后发送给输出流中。
如果属性是一个对象,将调用toString()方法。它的使用方法:
<jsp:getProperty name=“beanName”property=“propertyName”/>
(1)name=“beanName”:是必选项。其值是Bean的名字,为在这个之前用jsp:useBean引入的名称。
(2)property=“propertyName”:是必选属性。其值为所指定的Bean的属性名。
<jsp:getProperty>标签有一些限制:不能使用此标签检索一个已经被索引了的属性。
<jsp:useBean>
<jsp:useBean>标签用来在JSP页面中创建一个Bean实例,并指定它的名字及作用范围。它保证对象在标签指定的范围内可以使用。其语法定义:
<jsp:useBean id=“id” scope=“page|request|session|application” typeSpec/>
其中id是一个大小写相关的名字,用来表示这个实例;scope表示此对象可以使用的范围;typeSpec可以是以下四者之一:
class=“className”
class=“className” type=“typeName”
beanName=“beanName” type=“typeName”
type=“typeName”
(1)id=“name”
这在所定义的范围中确认Bean的变量。在定义某个JavaBean时,需要指定它的ID,通过此ID对JavaBean的实例对象进行引用。如果要使用的是一个已经创建好的Bean,那么这个ID的值必须与原来的哪个ID值一致。
(2)scope=“page|request|session|applicaton”
其值表示Bean存在的范围及ID变量名的有效范围。其默认值是page。
page 能够在包含<jsp:useBean>标签的JSP文件及此文件中的所有静态包含文件中使用Bean,直到页面执行完毕向客户端发会响应或转到另一个文件为止。超出这个范围Bean就失效了。
request 在请求的范围内使用有效。可以使用request对象访问Bean,比如:request.getAttribute(“name”);其中name是指 Bean实例化的名字。
session 从创建Bean开始,就可以在session有效范围内使用这个Bean,这个Bean对于 JSP来说是共享的。需要注意的是,在创建Bean的JSP文件中的<%@page %> 指令中必须指定session=“true”,否则会导致一个致命的错误发生。
application 同session一样,从创建Bean开始,就可以在任何使用相同application的JSP文件中使用Bean。Application对象在应用服务器启动时就创建了,直到应用服务器关闭。这个Bean存在于整个application生存周期内,任何在此分享application的JSP文件都可以使用同一Bean.
(3)class=“className”
这是Bean的类路径和类名。这个class不能是抽象的,必须有一个公用的、没有参数的构造器。
(4) BeanName=“beanName” type=“typeName”
使用instantiate方法从一个class中实例化一个Bean,同时还可以指定Bean的类型。
.class文件的名称,Bean包名或者包含该Bean的串行化文件(.ser文件).仅当Bean不存在于指定的作用域中时,才使用此属性.还必须使用类型属性来指定要将何种类型的Bean实例化.beanName属性不能与class属性一起使用.此值区分大小写.
注:使用beanName主要用来实例化一个串行化的Bean,而不是用来从一个类创建一个全新的实例.如果Bean还没有创建,beanName属性传给java.beans.Bean.instantiate()方法,由类加载器对象进行实例化.并首先假定存在一个串行化的Bean(带有扩展名.ser),然后会将其激活.如果这个操作失败,它就会实例化一个新的实例.
串行化:对象通过写出描述自己的状态的数值来记录自己,这个过程称为对象的串行化(serialization)
(5)type=“typeName”
type可以是一个类本身(class),也可以是一个类的父类,或者是一个类的接口。如果没有使用class或BeanName指定type,Bean将不会被实例化。
注:不能同时使用class和BeanName。BeanName表示Bean的名字,其形式为”a.b.c”。