![自定义标签和新特性_第1页](http://file4.renrendoc.com/view/bf3b6305c8c92781ca80c309ad9551e1/bf3b6305c8c92781ca80c309ad9551e11.gif)
![自定义标签和新特性_第2页](http://file4.renrendoc.com/view/bf3b6305c8c92781ca80c309ad9551e1/bf3b6305c8c92781ca80c309ad9551e12.gif)
![自定义标签和新特性_第3页](http://file4.renrendoc.com/view/bf3b6305c8c92781ca80c309ad9551e1/bf3b6305c8c92781ca80c309ad9551e13.gif)
![自定义标签和新特性_第4页](http://file4.renrendoc.com/view/bf3b6305c8c92781ca80c309ad9551e1/bf3b6305c8c92781ca80c309ad9551e14.gif)
![自定义标签和新特性_第5页](http://file4.renrendoc.com/view/bf3b6305c8c92781ca80c309ad9551e1/bf3b6305c8c92781ca80c309ad9551e15.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
自定义标签和新特性第一页,共105页。网络编程第7章自定义标签和新特性第二页,共105页。主题章节内容本章小结课后习题课外读物第三页,共105页。章节内容7.0引言7.1自定义标签7.2JSP2.0的新特性第四页,共105页。7.0引言为了减少JSP中的脚本,JavaEE规范允许开发人员自定义标签。
从JSP1.1开始增加了自定义标签库规范,自定义标签库是一种非常优秀的表现层组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的功能。在本章的内容中,将详细讲解JSP中自定义标签和JSP2新特性的基本知识,为后续的学习打下基础。第五页,共105页。7.1.1自定义标签概述7.1.2自定义标签种类7.1.3自定义标签的开发7.1自定义标签第六页,共105页。7.1.1自定义标签概述自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时被转化为servlet,标签转化为对应标签处理器(taghandler)对象的操作。接着当servlet执行时Web容器(container)调用那些操作。自定义标签特点可以通过调用页面传递的属性进行自定义。可以访问JSP页面上可能的所有对象。可以修改由调用页面产生的响应。可以相互间通信。你可以创建并初始化一个JavaBean组件,创建一个变量引用标签中的bean,接着在其它的标签中引用该bean。可以在一个标签中嵌套另一个,可以在JSP页面中进行复杂的交互。第七页,共105页。声明和使用标签描述标签开发和部署标签处理器自定义标签的描述第八页,共105页。1.声明和使用标签
可以通过在页面中使用下面的指令来声明在JSP中使用标签库:<%@tagliburi=”WEB-INF/testtag.tld”prefix=”tt”%>该uri属性引用了唯一识别的标签库描述符(TLD),该URI可以是直接的也可以是间接的。Prefix属性定义了区分其它标签的方法。之后可以使用标签库中的hello标签,例如:….<tt:hello/>….自定义标签的描述第九页,共105页。自定义标签的描述2.描述标签
在标签库描述文件中,我们可以描述每个具体的自定义标签。标签库描述文件必须以后缀为.tld命名。TLD文件保存在WEB-INF目录中,你可以直接或间接的引用TLD。下面的标签库指令直接引用了TLD文件:<%@tagliburi=”/WEB-INF/testtag.tld”prefix=”tt”%>下面的标签库指令使用了短的逻辑名来间接引用TLD:<%@tagliburi=”/testtag”prefix=”tt”%>如果想使用逻辑名,我们需要将逻辑名/testtag映射到绝对路径/WEB-INF/testtag.tld第十页,共105页。自定义标签的描述我们在web.xml中配置如下:<taglib><taglib-uri>/testtag</taglib-uri><taglib-location>/WEB-INF/testtag.tld</taglib-location></taglib>第十一页,共105页。自定义标签的描述3.开发和部署标签处理器
对于每个自定义标签,我们需要开发相应的标签处理器(taghandler)。这是我们的重点,我们再后面的章节里会展开。部署标签处理器的两种方法:将编译过的标签处理器类部署到项目的WEB-INF/classes目录下,这种方法应用在开发自己的标签或标签处理器类数目较少的情况。将编译过的标签处理器类打包成jar文件,之后部署到项目的WEB-INF/lib目录下。这种方法应用在需要导入第三方开发的标签或标签处理器类数目较多的情况。第十二页,共105页。7.1.2自定义标签种类根据对体内容的不同行为,可以将自定义标记分为两种类型:处理体内容的标记。
对体内容进行操作的标记,它必须继承接口
javax.Servlet.jsp.tagext.BodyTag。简单标记。
不对体内容进行处理的标记。它必须继承接口javax.Servlet.jsp.tagext.Tag。
第十三页,共105页。处理体内容的标记对于体标记的具体处理过程如下:(1)Web容器设置标记处理器的pageContext属性来初始化标记处理器。(2)Web容器设置标记处理器的parent属性(如果标记不被其他标记包含,则该属性为null)。(3)设置标记开发定义的标记参数(4)Web容器调用标记处理器的doStartTag()方法。(5)调用SetBodyContent()方法。(6)调用doInitBody()方法。(7)调用doAfterBody()方法。(8)Web容器调用标记处理器的doEndTag()方法。(9)Web容器调用标记处理器的release()方法,释放标记处理执行期间使用的资源,重置标记处理器的属性状态等。第十四页,共105页。简单标记简单标记是不对体内容进行处理的标记。简单标记分为两种:1)没有体及属性的标签:
<tt:simple/>2)带有属性的标签:
自定义标签可以含有属性。属性列于起端标签,有这样的语法:attr=”value”。属性值用于自定义标签的行为,就像方法中定义的参数一样。
在下面的例子中,一个属性制订了一个请求参数:name:
<tt:greetingname=”zjf”>第十五页,共105页。简单标记简单标记的处理过程如下:(1)Web容器设置标记处理器的pageContext属性来初始化标记处理器。(2)Web容器设置标记处理器的parent属性(如果标记不被其他标记包含,则该属性为null)。(3)设置标记开发定义的标记参数。(4)Web容器调用标记处理器的doStartTag()方法。(5)Web容器调用标记处理器的doEndTag()方法。(6)Web容器调用标记处理器的release()方法,释放标记处理执行期间使用的资源,重置标记处理器的属性状态等。第十六页,共105页。简单标记定义脚本变量的标签
自定义标签可以定义在脚本中使用的变量。下面的例子展示了如何定义并使用包含从JNDIlookup返回的对象的脚本变量。这个例子包含企业bean,事务处理,数据库,环境入口等。<t:lookupid=”tx”type=”UserTransaction”name=”java:comp/UserTransaction”/><%tx.begin();%>第十七页,共105页。7.1.3自定义标签的开发要完成一个标签的开发,需要具有以下几个部分:为标签开发一个标签处理器(标签处理类.java)在标签库中声明标签描述符(标签描述文件.tld)JSP页面(<%@taglib%>)(可选)在web.xml文件中配置映射名称。第十八页,共105页。标签处理器标签处理器是由Web容器调用的,用来处理运行的包含标签的JSP页面。标签处理器必须实现Tag或BodyTag接口。这些接口可以携带Java对象并产生一个标签处理器。对新创建的处理器,你可以使用TagSupport及BodyTagSupport类作为基类,这些基类接口在javax.servlet.jsp.tagext包中。第十九页,共105页。标签处理器表13-1第二十页,共105页。标签处理器(1)对于简单标签:我们必须实现doStartTaganddoEndTag方法,其中doStartTag必须返回SKIP_BODY这个常量,因为简单标签没有体doEndTag返回EVAL_PAGE,如果想要继续执行JSP页面的其它部分,否则返回SKIP_PAGE对于标签的每个属性,你必须定义属性名和实现对属性的getter/setter方法,注意这里要符合JavaBean的默认命名规范第二十一页,共105页。标签处理器(2)对于有体的标签:我们必须实现doStartTag
和doEndTag方法,可以实现doAfterBody
,doInitBody
和setBodyContent方法,其中doStartTag可能返回SKIP_BODY这个常量(如果没有体),或者EVAL_BODY_INCLUDE,EVAL_BODY_BUFFERED(如果你想使用体的内容)doEndTag返回EVAL_PAGE,如果想要继续执行JSP页面的其它部分,否则返回SKIP_PAGEdoAfterBody方法可以返回EVAL_BODY_AGAIN(如果想多次使用体),或者SKIP_BODY第二十二页,共105页。标签处理器
这些方法由JSP页面的servlet任何时候调用。当遇到标签的起始处时,JSP页面的servlet调用方法来初始化处理器接着调用处理器的doStartTag方法,当遇到结束点时,处理器的方法doEndTag被调用。另外的一些方法在标签相互通信时使用。
标签处理器有API接口来与jsp页面通信。其API入口点是pagecontext(javax.servlet.jsp.PageContext)。通过API,处理器可以返回其它隐含对象(request,session,application)。
隐含对象有些属性,它们可以通过使用[set|get]方法来调用。如果标签嵌套,标签处理器也要访问相应的标签。第二十三页,共105页。标签库描述符
标签库描述符是XML格式的文档。TLD包含库的所有信息及库中的每个标签。TLD由Web容器使用来验证标签并由JSP页面开发工具来使用。TLD文件必须以扩展名.tld为后缀。这类文件保存在WEB-INF目录中或它的子目录中,当你使用部署工具将TLD加到WAR中时,它会自动的加入到WEB-INF中。TLD文件开头格式:<?xmlversion=”1.0”encoding=”ISO-8859-1”?><!DOCTYPEtaglibPUBLIC“-//SunMicrosystems,Inc.//DTDJSPTagLibrary1.2//EN”>第二十四页,共105页。标签库描述符TLD的根元素是taglib,子元素列表如下:第二十五页,共105页。taglib子元素元素listener
标签库可以指定一些类——事件监听类。(参照处理servlet生命周期事件)。这些监听类都作为listener元素列于TLD中,网络容器将实例化监听类并通过与在WAR中定义的监听类类似的方法来注册。不像WAR级的监听类,标签库中注册的监听类没有定义顺序。Listener元素的唯一子元素是listener-class,它必须包含监听类名的全称。元素tag
库中的每个标签都有一个给定的名称及该标签的处理器来描述,标签创建的脚本变量信息,标签属性信息。脚本变量信息可以直接在TLD中给出或通过标签的额外信息获取。每一属性都包含说明是否需要该属性,它的值是否可以通过请求时表达式来决定,及其属性类型。第二十六页,共105页。tag子元素下表列出了标签的子元素信息:第二十七页,共105页。简单标签的开发简单标签处理器必须实现Tag接口(或继承TagSupport)的doStartTag及doEndTag两个方法。方法doStartTag在开始遇到时被调用,并返回SKIP_BODY,因为简单标签没有体。方法doEndTag在标签结束时被调用,如果其它页面需要使用则返回EVAL_PAGE,否则返回SKIP_PAGE。第二十八页,共105页。简单标签的开发最简单的标签:<tt:simple/>将由下面的标签处理器来实现:publicSimpleTagextendsTagSupport{
publicintdoStartTag()throwsJspException{
try{
pageContext.getOut().print(“HelloWorld.”);
}catch(Exceptione){thrownewJspTagException(“SimpleTag:”+e.getMessage());}
returnSKIP_BODY;
}
publicintdoEndTag(){
returnEVAL_PAGE;
}
}TLD元素body-content:tld中没有体的标签必须用body-content元素来声明体内容为空:
<body-content>empty</body-contnent>第二十九页,共105页。简单标签的开发带属性的标签对于每一个标签属性,你必须在标签处理器中定义一个属性及get/set方法来遵循JavaBean的结构。例如,下面的处理器处理<tt:greetingname=”Lixin”>标签.importjavax.servlet.jsp.tagext.*;importjavax.servlet.jsp.*;publicclassGreetingTagextendsTagSupport{privateStringname;publicvoidsetName(Stringname){=name;}publicStringgetName(){returnname;}publicintdoStartTag()throwsJspException{returnSKIP_BODY;}第三十页,共105页。简单标签的开发
publicintdoEndTag()throwsJspException{try{//getJspWriter,sendcontenttoclientpageContext.getOut().print("Hello,"+name);}catch(java.io.IOExceptione){e.printStackTrace();}returnEVAL_PAGE;}}注意:如果属性命名为id,标签处理器继承了TagSupport类,你不需要定义该属性及set/get方法,因为已经由TagSupport定义了。第三十一页,共105页。简单标签的开发TLD元素attribute对于每一个标签属性,你必须指定该属性是否必须,该标签的知是否可以通过表达式确定,属性类型在元素attribute中。对于静态类型数值通常为java.lang.String。如果元素rtexprvalue是true或者是yes,元素类型决定了返回值类型。<attribute>
<name>attr1</name>
<required>true|false|yes|no</required>
<rtexprvalue>true|false|yes|no</rtexprvalue>
<type>fully_qualified_type</type><attribute>第三十二页,共105页。简单标签的开发
如果属性不必须,标签处理器应该指定一个默认值标签元素tt:greeting声明了一个属性name不必须,且它的值可以有一个表达式来赋值。<tag>
…
<body-content>JSP</body-content>
……
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
……</tag>第三十三页,共105页。带体的标签开发标签处理器在处理含标签体的标签时实现有所不同,主要取决于处理器是否需要与体交互。这里交互指的是标签处理器读取或修改体的内容。(1)标签处理器不与体交互(2)标签处理器与体交互第三十四页,共105页。带体的标签开发
标签处理器不与体交互如果处理器不与体交互,标签处理器需要实现Tag接口(或继承TagSupport)。如果标签的体需要计算,方法doStartTag需要返回EVAL_BODY_INCLUDE;否则,则返回SKIP_BODY.
如果标签处理器需要重复计算体,则该标签需要实现接口IterationTag或者继承TagSupport。如果标签决定体需要再计算一次则从doStartTag和doAfterBody返回EVAL_BODY_AGAIN。第三十五页,共105页。带体的标签开发标签处理器与体交互如果标签处理器需要与体交互,标签处理器必须实现BodyTag接口(或继承BodyTagSupport),这样的处理器实现了方法doInitBody,doAfterBody。这些方法与传递到标签处理器的体内容交互。doInitBody方法
该方法在体内容设置之前求值之后被调用。通常使用该方法初始化体内容。doAfterBody方法
该方法在体内容求值之后被调用。像方法doStartTag一样,doAfterBody方法必须返回指示是否继续计算体。这样,如果体需要再计算一次,就像实现了迭代标签一样,doAfterBody方法应返回EVAL_BODY_BUFFERED,否则返回SKIP_BODY.第三十六页,共105页。带体的标签开发标签体支持一些方法来读写它的内容。标签处理器可以使用体内容的getString/getReader方法从体中获取信息,并通过writeOut方法来将体内容写到输出流。写提供writeOut方法,该方法可以通过使用标签处理器的方法getPreviousOut来获取。该方法确保标签处理器的结果对封闭的标签处理器可行。下面的例子从体中读取内容并传递到一个执行查询的对象。由于体不需要重复计算,所以doAfterBody返回SKIP_BODY。第三十七页,共105页。带体的标签开发
publicclassQueryTagextendBodyTagSupport
{…
publicintdoAfterBody()throwsJspTagException
{
BodyContentbc=getBodyContent();
Stringquery=bc.getString();
bc.clearBody();
try
{
Statementstm=connection.createStatement();
result=stm.executeQuery(query);
}catch(SQLExceptione){thrownewJspTagException(“QueryTag:”+e.getMessage());}
returnSKIP_BODY;
}…
}第三十八页,共105页。带体的标签开发TLD元素body-content
对于有体的标签,必须用下面的方法指定体内容的类型:
<body-content>JSP|tagdependent</body-content>
体内容包含自定义及核心标签,脚本元素,HTML文本都统一为JSP。
注意:body-content元素的值不会影响体处理器的解释
另外一个例子,需要对体重复计算,所以doAfterBody返回EVAL_BODY_AGAIN第三十九页,共105页。带体的标签开发publicclassRepeatTagextendsBodyTagSupport{privateintcount;privateStringname;publicvoidsetCount(intn){count=n;}publicintgetCount(){returncount;}publicvoidsetName(Stringname){=name;System.out.println("setName:"+name);}publicStringgetName(){return;}publicintdoStartTag()throwsJspException{System.out.println("name="+name);if(name!=null)pageContext.setAttribute("name",name);if(count>0)returnEVAL_BODY_BUFFERED;elsereturnSKIP_BODY;}第四十页,共105页。带体的标签开发publicintdoAfterBody()throwsJspException{if(count>1){count--;returnEVAL_BODY_AGAIN;}returnSKIP_BODY;}publicintdoEndTag()throwsJspException{BodyContentbc=getBodyContent();if(bc!=null){try{//writecontentofbodytoenclosingwriterbc.writeOut(bc.getEnclosingWriter());}catch(java.io.IOExceptione){e.printStackTrace();}}returnEVAL_PAGE;}publicvoidsetBodyContent(BodyContentbodycontent){this.bodyContent=bodycontent;第四十一页,共105页。带体的标签开发在自定义标记中引入脚本变量,需要以下几个步骤:
(1)实现一个TagExtraInfo子类来定义变量。
(2)在标记描述文件中引入TagExtraInfo子类。
(3)编写代码在标记处理器本身的页面上下文中引入变量
第四十二页,共105页。带体的标签开发实现一个TagExtraInfo子类来定义变量importjavax.servlet.jsp.tagext.*;
//TagExtraInfo用于提供一些在标签翻译时相关的信息。
publicclassIterateTEIextendsTagExtraInfo
{
publicIterateTEI()
{
super();
}
publicVariableInfo[]getVariableInfo(TagDatadata)
{
returnnewVariableInfo[]
{
newVariableInfo(
data.getAttributeString("name"),
data.getAttributeString("type"),
true,
VariableInfo.NESTED);
};
}
}
第四十三页,共105页。带体的标签开发编写代码在标记处理器本身的页面上下文中引入变量VariableInfo(String
varName,StringclassName,Booleandeclare,intscope)来定义,构造函数各参数意义如下:
varName:变量名称,JSP中用它来访问脚本变量。
className:类名称,用来定义变量类型。
declare:作为一个boolean参数,用来控制是否要创建一个新的变量。一般情况默认值为true。
Scope:定义标记中变量的范围。自定义标记中定义的变量有三种类型的范围:NESTED、AT_begin和AT_end。如果定义的范围是Nested,则Web容器只能在定义标记体中获取该变量;如果定义的范围是AT_begin,则只有在标记打开之后,Web容器才能获取该变量;如果定义的范围是AT_end,则只有在标记关闭之后,Web容器才能获取该变量第四十四页,共105页。带体的标签开发tld配置
<name>iterate</name>
<tag-class>com.tfsoftware.taglib.IterateTag</tag-class>
<tei-class>com.tfsoftware.taglib.IterateTEI</tei-class>
<body-content>jsp</body-content>
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute><attribute>
<name>type</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue></attribute>
第四十五页,共105页。嵌套或协作标签
通过共享对象实现标签的协作JSP技术支持两种类型的对象共享。
第一种类型需要共享对象命名、存储在pagecontext中。为了让其它标签访问,标签处理器使用pageContext.getAttribute(name,scope)方法。
第二种方法是由封闭的标签处理器创建的对象对内部的标签处理器是可访问的。这种形式的对象共享有个优点,它使用了对象私有的名字空间,这样减少了潜在的命名冲突。第四十六页,共105页。嵌套或协作标签
为访问闭合标签创建的对象,标签处理器必须首先通过静态方法TagSupport.findAncestorWithClass(from,class)或TagSupport.getParent方法获得封闭标签。前一个方法应该在特定的嵌套的标签处理器不能保证时使用。一旦ancestor返回,标签处理器就能访问任何静态或动态创建的对象。静态创建的对象是父类的成员。私有对象也可以动态的创建。这样的对象可以通过方法setValue存储在标签处理器中,可以通过getValue方法返回。第四十七页,共105页。嵌套或协作标签一个例子是很常用的switch/case流程控制packagesample;importjavax.servlet.jsp.*;importjavax.servlet.jsp.tagext.*;importjava.util.Hashtable;importjava.io.Writer;importjava.io.IOException;publicclassSwitchTagextendsTagSupport{Stringvalue;publicSwitchTag(){super();}publicvoidsetValue(Stringvalue){this.value=value;}publicStringgetValue(){returnvalue;}publicintdoStartTag(){returnEVAL_BODY_INCLUDE;}}第四十八页,共105页。嵌套或协作标签publicclassCaseTagextendsTagSupport{Stringvalue;publicintdoStartTag()throwsJspTagException{//SwitchTagparent=(SwitchTag)findAncestorWithClass(this,SwitchTag.class);SwitchTagparent=(SwitchTag)this.getParent();try{if(parent.getValue().equals(getValue())){returnEVAL_BODY_INCLUDE;}else{returnSKIP_BODY;}}catch(NullPointerExceptione){returnSKIP_BODY;}}publicvoidsetValue(Stringvalue){this.value=value;}publicStringgetValue(){returnvalue;}}第四十九页,共105页。嵌套或协作标签使用EXISTS的子查询时需注意:
EXISTS关键字前面没有列名、常量或其他表达式。由EXISTS引出的子查询,其选择列表达式通常都用(*).这是因为,带EXISTS的子查询只是测试是否存在符合子查询中指定条件的行,所以不必列出列名。带EXISTS的子查询与前面的不相关子查询有一个明显区别,即子查询的查询条件依赖于外部查询的某个属性值,我们称这类查询为相关子查询。
求解相关子查询的过程不能像求解不相关子查询那样,一次将子查询求解出来,然后求解外部查询,相关子查询的内部查询由于与外部查询有关,因此必须反复求值,一般处理过程如下:1)首先取外部查询中Class表的第一行记录,根据它与内部查询相关的属性值(即ClassID值)处理内部查询,若WHERE子句返回值为真(即内部查询结果非空),则取此记录放入结果集中。2)再检查Student表的下一行记录。3)重复执行步骤2,直至student表全部检查完毕。第五十页,共105页。嵌套或协作标签综合使用这几个标签的JSP如下所示:testTag.jsp:<%@pagecontentType="text/html;charset=GBK"%><%@tagliburi="/WEB-INF/test.tld"prefix="tt"%><html><head><title>GreetingTagTest</title></head><body><tt:switchvalue="dark"><tt:casevalue="light"><P>Thisislight.</P></tt:case><tt:casevalue="Dark"><P>ThisisDark.</P></tt:case><tt:casevalue="dark"><P>Thisisdark.</P></tt:case></tt:switch></body></html>第五十一页,共105页。7.2JSP2.0的新特性7.2.1JSP2.0新特性概述7.2.2配置JSP属性7.2.3JSP的表达式7.2.4自定义标签TagFile第五十二页,共105页。7.2.1JSP2.0新特性概述和JSP1.2相比,JSP2.0主要增加了如下所示的新特性。(1)直接配置JSP属性。(2)表达式语言。(3)简化的自定义标签API。(4)Tag文件语法。第五十三页,共105页。7.2.2配置JSP属性JSP属性主要包括4个方面,具体说明如下所示。是否允许使用表达式语言:可以使用<el-ignored/>元素确定,默认值为false,即允许使用表达式语言。是否允许使用JSP脚本:可以使用<scripting-invalid/>元素确定,默认值为false,即允许使用JSP脚本。声明JSP页面的编码可以:使用<encoding/>元素确定,配置该元素后,可以代替每个页面里page指令contentType属性的charset部分。使用隐式包含:可以使用<include-prelude/>和<include-coda/>元素确定,可以代替在每个页面里使用include编译指令来包含其他页面。第五十四页,共105页。在JSP中使用表达式语言的格式如下所示。${expression}1.对算术运算符或逻辑运算符的支持2.表达式语言的内置对象3.使用自定义函数第五十五页,共105页。
关于ExpressionLanguage
EL变量
运算符
隐含对象
保留字7.2.3JSP的表达式第五十六页,共105页。
关于ExpressionLanguageJSP2.0將ExpressionLanguage(以下简称EL)整合进JSP标准规格。EL并非全新的语言,最早出现于JSTL1.0当中,被用来简化数据存取的相关操作。由于EL已是JSP的标准,因此用户可以选择直接在JSP网页当中使用EL替代Java进行数据的存取操作。EL有其专属的一套语法,包含了两项基本要素:变量与运算符。EL內建隐含对象(implicitvariables),以Java集合对象的型态出现,其中储存了网页的各种信息,包含session、cookie和网页传输过程当中所使用的参数值。第五十七页,共105页。通过PAGE指令来说明是否支持EL表达式,具体举例:<%@pagecontentType="text/html;charset=GB2312"isELIgnored="false"%>//声明可以使用EL表达式,如果为"ture",则表示忽略${,即不能使用EL表达式。<html><head><title>EL</title></head><%!intcount=0;%><bodybgcolor="#ffffff">${count}//如何在这里用EL表达式输入上面定义的count</body></html>第五十八页,共105页。EL语法
EL必须以一个金钱表示符号加上左大括号${开始,并且以右大括号}作结束。
${ELexpression} 1.对算术运算符或逻辑运算符的支持 2.表达式语言的内置对象 3.使用自定义函数第五十九页,共105页。7.2.3JSP的表达式
关于ExpressionLanguage
EL变量
运算符
隐含对象
保留字第六十页,共105页。
EL变量
一个储存了特定数据内容的符号,EL可以直接对其作存取,或是结合运算符进行必要的运算之后作输出。
EL存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。第六十一页,共105页。系统从Page,Request,Session,Application范围查找该变量。途中找到,就直接回传,不再继续找下去,如全范围内都没有,则回传null。属性范围在EL中的名称
Page
PageScope
Request
RequestScope
Session
SessionScope
Application
ApplicationScope第六十二页,共105页。7.2.3JSP的表达式
关于ExpressionLanguage
EL变量
运算符
隐含对象
保留字第六十三页,共105页。1.算术运算符有五个:+、-、*或$、/或div、%或mod
2.关系运算符有六个:==或eq、!=或ne、<或lt、>或gt、<=或le、>=或ge
3.逻辑运算符有三个:&&或and、||或or、!或not
4.其它运算符有三个:Empty运算符、条件运算符、()运算符
运算符第六十四页,共105页。
运算符运算符说明.存取beanproperty或是mapentry[]存取arrayorList元素()改变运算顺序?:条件式三元运算condition?ifTrue:ifFalse+加法运算-减法运算*乘法运算/ordiv除法运算%ormod模数运算第六十五页,共105页。运算符说明==oreq对等运算!=orne不相等运算<orlt小于比较运算>orgt大于比较运算<=orle小于或等于比较运算>=orge大于或等于比较运算&&orand逻辑AND运算||oror逻辑OR运算!ornot布尔补码运算empty空值运算func(args)函数调用第六十六页,共105页。
运算符.1运算符(.)与方括号([]).2算术运算符.3关联运算符.4逻辑运算符.5empty运算符.6条件式三元运算符.7运算符优先级第六十七页,共105页。.1运算符(.)与方括号([])无论actionelements或是隐含对象的数据内容,均是一种集合(collection)对象,EL可以通过点运算符(.)或是方括号([])对其作存取。
当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用[]。如果要动态取值时,就可以用[]来做,而“.”无法做到动态取值。${param.yearValue}${param[“yearValue”]},${param[data]}第六十八页,共105页。.2算术运算符运算符说明+对两个数值进行加法运算-对两个数值进行减法运算*对两个数值进行乘法运算/或是div对两个数值进行除法运算%或是mod对两个数值进行模数运算第六十九页,共105页。表达式A{+、-、*}B
首先如果A与B为null,则运算之后的结果,是一个long型态的0。A或B其中一个是BigDecimal,则两者均会转换成为BigDecimal。运算符
返回结果运算符+A.add(B)运算符-A.subtract(B)运算符*A.multiply(B)第七十页,共105页。A或B为Float、Double或是包含.、e或是E:的字符串(String):如果A或是B其中之一为BigInteger,两者均会强制转型为BigDecimal,否则转型为Double,然后进行运算。如果A或B为BigInteger,两者均会被强制转换成为BigInteger,然后进行表8-4中的相关运算。运算符返回结果运算符+A.add(B)运算符-A.subtract(B)运算符*A.multiply(B)第七十一页,共105页。如果非上述状况,A与B一律转换成为Long,然后进行运算。如果运算结果产生例外,则为错误结果。
第七十二页,共105页。表达式A{/,div}B如果A与B为null,则运算之后回传一个long型态的0。假若A或B为BigDecimal或是BigInteger,两者被强制转换成为BigDecimal并且返回A.divide(B,BigDecimal.ROUND_HALF_UP)的运算结果。如果非上述情形,A与B强制转换成为Double然后进行运算。最后,如果运算结果产生例外,则为错误结果。第七十三页,共105页。表达式A{%,mod}B如果A与B为null,返回Long型态数值0。假若A或B为Float、Double或是包含.、e或是E的字符串(String),将A与B两者强制转换为Double之后进行运算。如果A或B为BigInteger,强制转换为BigInteger之后,返回A.remainder(B)的运算结果。A与B如果非上述状况则转换为Long进行运算。最后,若运算结果发生例外,则为错误结果。第七十四页,共105页。.3关联运算符运算符说明==andeq等于!=andne不等于<andlt小于>andgt大于<=andle小于等于>=andge大于等于第七十五页,共105页。表达式A{<,>,<=,>=,lt,gt,le,ge}B若是A等于B,运算符<=,le,>=或是ge返回true的结果。当A或是B其中之一为null,返回false。假若A或B为BigDecimal,将A与B强制转换成为BigDecimal然后返回A.compareTo(B)的运算结果。如果A或B为Float或是uble,强制转换Double之后,进行运算。如果A或B为BigInteger,强制转换BigInteger,然后返回A.compareTo(B)的比较结果。如果A或B为Byte、hort、Character、Integer或是Long,强制转换成为Long然后进行运算。当A或是B其中之一为字符串(String),强制转换成为String之后依字母进行字符串比较。第七十六页,共105页。表达式A{==,!=,eq,ne}B当A或是B其中之一为null,返回false运算结果。若A或者B为BigDecimal,两者均会强制转换成为BigDecimal再进行运算,对于==运算符而言,回传一个A.equals(B)的结果,而!=运算符则返回!A.equals(B)的结果。当A或者B为Float或是Double,两者均会强制转换成为Double然后进行运算。若A或者B为BigInteger,两者均会强制转换成为BigInteger,其中若是运算符为==,回传A.equals(B),!=则返回!A.equals(B)的运算结果。若A或者B为Byte、Short、Character、Integer或是Long,将被强制转换成为Long之后进行运算。若A或者B为Boolean,将被强制转换成Boolean作运算。若A或者B为String,将被强制转换成String作运算。第七十七页,共105页。.4逻辑运算符运算符说明&&或and逻辑AND运算||或or逻辑OR运算!或not布尔值补码第七十八页,共105页。.5empty运算符empty被用来判断是否指定的值为null或是空值,并且返回一个代表判断结果的Boolean值,empty
的运用非常简单,如下式:${emptyA}其中的A为所要判断的值,下面为empty的运算规则:若是判断值A为null,返回true的运算结果,若是A
的值为空的字符串、数组或是集合对象,也返回true
的结果,除此之外,一律返回false。第七十九页,共105页。.6条件式三元运算符三元运算符针对特定判断式的运算结果,决定返回的值:${A?B:C}
A为判断式,如果A的结果为true,返回B,否则返回C值的结果。第八十页,共105页。.7
运算符优先级运算符优先级[].()-(unary)not!empty*/div%mod+-(binary)<><=>=ltgtlege==!=eqne&&and||or?:第八十一页,共105页。7.2.3JSP的表达式
关于ExpressionLanguage
EL变量
运算符
隐含对象
保留字第八十二页,共105页。与范围有关的隐含对象
与范围有关的EL隐含对象包含以下四个:pageScope、requestScope、sessionScope和applicationScope;与输入有关的隐含对象
与输入有关的隐含对象有两个:param和paramValues,它们是EL中比较特别的隐含对象。其他隐含对象
cookie等
隐含对象第八十三页,共105页。隐含对象隐含对象说明pageContext取得网页运行环境的相关信息pageScope取得page范围内特定属性的属性值requestScope取得request范围内特定属性的属性值sessionScope取得session范围内特定属性的属性值applicationScope取得application范围内特定属性的属性值param取得request对象的单一参数值paramValues取得request对象的参数值header取得request对象单一标头值headerValues取得request对象标头值cookie取得request对象的cookieinitParam取得网页运行环境的初始参数值第八十四页,共105页。EL对象与
request对象存取EL对象Request对象存取paramServletRequest.getParameter(Stringname)paramValuesServletRequest.getParameterValues(Stringname)headerHttpServletRequest.getHeader(Stringname)headerValuesHttpervletRequest.getHeaders(String)cookieHttpServletRequest.getCookies()第八十五页,共105页。.1pageContext.2范围变量.3param与paramValues.4header与headerValues.5cookie
.6initParam
第八十六页,共105页。.1pageContextpageContext对象代表网页本身,用户可以利用这个对象轻易获得网页相关信息,其中包含用户所传递的网页参数、用户名称与主机地址等。pageContext取得其他有关用户要求或页面的详细信息。
${pageContext.request.queryString}//判断session是否为新的
${pageContext.session.id}
//取得session的ID
${pageContext.servletContext.serverInfo}
//取得主机端的服务信息第八十七页,共105页。.2范围变量EL当中4个与范围有关的隐含对象,pageScope、requestScope、sessionScope和applicationScope,可直接用来存取属于特定范围内的变量值。从对象的名称,可以很轻易的了解这些对象的适用范围,除此之外,它们与JSP内建所的隐含对象基本上是相同的。EL
对象JSP
对象pageScopepageContextrequestScoperequestsessionScopesessionapplicationScopeapplication第八十八页,共105页。存取范围变量在JSP网页当中取得特定范围变量属性,必须引用getAttribute(),并且指定所要取得的变量名称: application.getAttribute("cname")通过EL的存取方式: ${applicationSame}第八十九页,共105页。.3param与paramValues
EL对象param与paramValues被设计用来提供使用request之外的一个选择,下表列出相同效果的request方法。ELrequest${param.paraName}request.getParameter(paraName)${paramValues.paraName}request.getParameterValues(paraName)第九十页,共105页。Param¶mValues存取param内容包含当前网页所有的request参数,这段程序代码取得其中名称为yearValue的参数值。${param.yearValue}。针对取得的参数内容,进一步对其作运算。${param.yearValue+100}param与paramValues最大的好处便是简化了request参数数据的存取。第九十一页,共105页。.4header与headerValues
Header与headerValues這两个对象可以达到
request对象取出HTTP标头信息的功能,语法也相对简单许多。${header["host"]}指定不同的标头名称,可直接返回相对的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 合伙人合作合同模板大全
- 2025年度股权认购合同(智能家居系统研发)
- 分期付款汽车贷款购车合同模板
- 2025年度会议中心场地租赁与配套服务合同正规范
- 2025年度智能交通系统设备采购合同示范文本
- 2025年度装配式建筑构件运输与仓储服务合同范本
- 洗车场承包经营合同(3篇)
- 2025年度健康医疗产业合伙经营管理合同
- 2025年国际集装箱运输代理合同协议范本
- 2025年度智慧农业平台建设合同续签申请书
- 《工作场所安全使用化学品规定》
- 装饰图案设计-装饰图案的形式课件
- 2022年菏泽医学专科学校单招综合素质考试笔试试题及答案解析
- 护理学基础教案导尿术catheterization
- ICU护理工作流程
- 广东版高中信息技术教案(全套)
- 市政工程设施养护维修估算指标
- 短视频:策划+拍摄+制作+运营课件(完整版)
- 石家庄铁道大学四方学院毕业设计46
- 分布式光伏屋顶调查表
- 部编版五年级语文下册第四单元课时作业本有答案
评论
0/150
提交评论