|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
大型的应用一般不会用这些框架(因为性能考虑);开发人员根据需要选择用一些框架,也可以不选用框架;不用框架并不代表要自己写框架;修改框架的可能性更小。js|页面JSP页面中的自界说标签2
带属性的标签
在标签handler中界说属性
关于每个标签属性,都必需在标签handler中界说一个属性和切合JavaBean布局标准的get和set办法。比方,logic:present标签的标签handler
<logic:presentparameter="Clear">
包括以下声明和办法:
protectedStringparameter=null;
publicStringgetParameter(){
return(this.parameter);
}
publicvoidsetParameter(Stringparameter){
this.parameter=parameter;
}
--------------------------------------------------------------------------------
注重,假如属人命名为id而且标签handler承继自TagSupport类,那末就不必要界说属性和set和get办法,由于它们已由TagSupport界说了。
--------------------------------------------------------------------------------
值为String的标签属性能够指定标签handler可用的隐式对象的一个属性。经由过程向隐式对象的[set|get]Attribute办法传送标签属性值能够会见一个隐式对象属性。这是将剧本变量名传送给标签handler的好体例,在这里剧本变量与贮存在页面高低文中的对象相干联(见隐式对象)。
attribute元素
关于每个标签属性,都必需在attribute元素中指定这个属性是不是是必须的、其值是不是能够由表达式断定、还大概指定属性的范例。关于静态值,范例老是java.lang.String。假如rtexprvalue元素是true大概yes,那末type元素界说会将任何指定的表达式的预期前往范例指定为属性的值。
<attribute>
<name>attr1</name>
<required>true|false|yes|no</required>
<rtexprvalue>true|false|yes|no</rtexprvalue>
<type>fully_qualified_type</type>
</attribute>
假如tag属性不是必须的,那末标签handler应当供应一个默许值。
logic:present标签的tag元素声明parameter属性不是必须的(由于标签还能够测试是不是存在别的实体,如bean属性)和其值能够由运转时表达式设置。
<tag>
<name>present</name>
<tag-class>org.apache.struts.taglib.
logic.PresentTag</tag-class>
<body-content>JSP</body-content>
...
<attribute>
<name>parameter</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
...
</tag>
属性考证
标签库的文档应当形貌标签属性的无效值。在转换JSP页面时,Web容器将强迫使用每个属性的TLD元素中包括的限定。
在转换时还用从TagExtraInfo派生的类的isValid办法考证传送给标签的属性。这个类也用于供应有关标签订义的剧本变量的信息(见供应有关剧本变量的信息)。
用TagData对象向isValid办法传送属性信息,它包括每个标签属性的属性-值元组。由于考证在转换时产生,以是在哀求时盘算的属性值将设置为TagData.REQUEST_TIME_VALUE。
<tt:twaattr1="value1"/>标签有以下TLDattribute元素:
<attribute>
<name>attr1</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
这个声明标明attr1的值能够在运转时断定。
上面的isValid办法反省attr1的值是不是为无效的布尔值。注重因为的attr1值能够在运转时盘算,以是isValid必需反省标签用户是不是选择了供应运转时价。
publicclassTwaTEIextendsTagExtraInfo{
publicbooleanisValid(Tagdatadata){
Objecto=data.getAttribute("attr1");
if(o!=null&&o!=TagData.REQUEST_TIME_VALUE){
if(((String)o).toLowerCase().equals("true")||
((String)o).toLowerCase().equals("false"))
returntrue;
else
returnfalse;
}
else
returntrue;}
}
带注释的标签
标签handler
带注释的标签的标签handler依据标签handler是不是必要与注释交互而有分歧的完成。我们说的交互的意义是标签handler读取大概修正注释的内容。
标签handler不与注释交互
假如标签handler不必要与注释交互,那末标签handler应当完成Tag接口(大概从TagSupport派生)。假如必要对标签的注释举行判别,那末doStartTag办法就必要前往EVAL_BODY_INCLUDE,不然,它应当前往SKIP_BODY。
假如标签handler必要重复地判别注释,那末它就应当完成IterationTag接口大概从TagSupport派生。假如它断定必要再次评价注释,那末它应当从doStartTag和doAfterBody办法前往EVAL_BODY_AGAIN。
标签handler与注释交互
假如标签handler必要与注释交互,那末标签handler必需完成BodyTag(大概从BodyTagSupport派生)。这类处置器一般完成doInitBody和doAfterBody办法。这些办法与由JSP页面的servlet传送给taghandler的注释内容交互。
注释内容撑持几种读取和写进其内容的办法。标签handler能够用注释内容的getString大概getReader办法从注释中提失信息,用writeOut(out)办法将注释内容写进一个输入流。为writeOut办法供应的writer是用标签handler的getPreviousOut办法失掉的。用这个办法包管标签handler的了局关于其核心标签handler是可用的。
假如必要对标签的注释举行判别,那末doStartTag办法必要前往EVAL_BODY_BUFFERED,不然它就应当前往SKIP_BODY。
doInitBody办法
在已设置注释内容以后、可是对它举行判别之前挪用doInitBody办法。一样平常用这个办法实行一切依附于注释内容的初始化。
doAfterBody办法
doAfterBody办法在判别了注释内容以后挪用。
像doStartTag办法一样,doAfterBody必需前往指明是不是持续判别注释的唆使。因而,假如应当再次判别注释,就像完成列举标签的情形,那末doAfterBody应当前往EVAL_BODY_BUFFERED,不然doAfterBody应当前往SKIP_BODY。
Release办法
标签handler应当在release办法中从头设置其形态并开释一切公有资本。
上面的例子读取注释的内容(它包括一个SQL查询)并将它传送给一个实行这个查询的对象。由于不必要对注释再次判别,以是doAfterBody前往SKIP_BODY。
publicclassQueryTagextendsBodyTagSupport{
publicintdoAfterBody()
throwsJspTagException{
BodyContentbc=getBodyContent();
//getthebcasstring
Stringquery=bc.getString();
//cleanupbc.clearBody();
try{
Statementstmt=connection.createStatement();
result=stmt.executeQuery(query);
}catch(SQLExceptione){
thrownewJspTagException("QueryTag:"+
e.getMessage());
}
returnSKIP_BODY;
}
}
body-content元素
关于有注释的标签,必需用body-content元素指定注释内容的范例:
<body-content>JSP|tagdependent</body-content>
注释内容包括自界说和中心标签、剧本元素和属于JSP的HTML笔墨。这是为Strutslogic:present标签声明的值。一切别的范例的注释内容――如传送给查询标签的SQL语句,都标志为tagdependent。
注重body-content元素的值不影响标签handler对注释的解读,这个元素只是由编写工具用于出现注释内容。
界说剧本变量的标签
标签handler
标签handler卖力创立剧本变量援用的对象并设置到页面能够会见的高低文中。它是用pageContext.setAttribute(name,value,scope)大概pageContext.setAttribute(name,value)办法完成这项事情的。一般传送给自界说标签的属性指定剧本变量对象的名字,经由过程挪用在利用局限对象中形貌的属性的get办法能够提取这个名字。
假如剧本变量的值依附于在标签handler高低文中呈现的一个对象,那末它能够用pageContext.getAttribute(name,scope)办法提取这个对象。
一样平常的一般历程是标签handler提取剧本变量、对对象实行一些处置、再用pageContext.setAttribute(name,object)办法设置剧本变量的值。
表16-4总结了对象能够有的感化域。感化域限定了对象的可会见性和寿命。
表16-4对象局限
名字
可会见性
寿命
page
以后页面
直到呼应被前往到用户大概哀求被传送给一个新页面
request
以后页面及一切包括大概转发页面
直到呼应被前往到用户
session
以后哀求和一切从统一个扫瞄器收回的后续哀求(取决于会话寿命)
用户会话的寿命
application
统一Web使用程序确当前和一切将来哀求
使用程序的寿命
供应有关剧本变量的信息
在界说剧本变量的标签中形貌的例子界说了用于会见图手札息的剧本变量:book
<bean:defineid="book"
name="bookDB"property="bookDetails"
type="database.BookDetails"/>
<fontcolor="red"size="+2">
<%=messages.getString("CartRemoved")%>
<strong><jsp:getPropertyname="book"
property="title"/></strong>
<br><br>
</font>
在转换包括这个标签的JSP页面时,Web容器会天生同步剧本变量与由变量援用的对象的代码。要天生这些代码,Web容器必要关于剧本变量的一些信息:
・变量名
・变量类
・变量是不是援用新的对象大概是现有对象
・变量的可用性
有两种办法供应这类信息:指定variableTLD子元素大概界说tagextrainfo类并在TLD中包括tei-class元素。用variable元素更复杂,可是天真性要差一些。
variable元素
variable元素有以下子元素:
・name-given:变量名为常量
・name-from-attribute:一个属性的名字,其转换时(translation-time)值将给出属性的名字
必需有name-given大概name-from-attribute当中的一个。以下子元素是可选的:
・variable-class―变量的完整限制名。默许为java.lang.String。
・declare―变量是不是援用新对象。默许为True。
・scope―界说的剧本变量的感化域。默许为NESTED。表16-5形貌了剧本变量的可用性和必需设置大概从头设置变量值的办法。
表16-5剧本变量可用性
值
可用性
办法
NESTED
入手下手和停止标签之间
在完成BodyTag的标签handler的doInitBody和doAfterBody办法中,不然,在doStartTag中
AT_BEGIN
从入手下手标签到页面的停止
在完成BodyTag的标签handler的doInitBody和doAfterBody办法中,不然,在doStartTag和doEndTag中
AT_END
在停止标签以后直到页面的停止
在doEndTag中
Strutsbean:define标签的完成切合JSP标准版本1.1,它请求界说tagextrainfo类。JSP标准版本1.2增添了variable元素。能够为bean:define标签订义上面的variable元素:
<tag>
<variable>
<name-from-attribute>id</name-from-attribute>
<variable-class>database.BookDetails</variable-class>
<declare>true</declare>
<scope>AT_BEGIN</scope>
</variable>
</tag>
TagExtraInfo类
经由过程扩大类javax.servlet.jsp.TagExtraInfo界说tagextrainfo类。TagExtraInfo.ATagExtraInfo必需完成getVariableInfo办法以前往包括以下信息的VariableInfo对象数组:
・变量名
・变量类
・变量是不是援用新对象
・变量可用性
Web容器向getVariableInfo办法传送包括每个标签属性的属性-值元组的名为data的参数。这些属性能够用于为VariableInfo对象供应剧本变量名和类。
Struts标签库供应有关由DefineTeitagextrainfo类中的bean:define标签创立的剧本变量的信息。因为剧本变量的name(book)和class(database.BookDetails)作为标签属性传送,以是能够用data.getAttributeString办法提取它们,并用于添补VariableInfo机关函数。要使剧本变量book用于页面的其他中央,book的感化域设置为AT_BEGIN。
publicclassDefineTeiextendsTagExtraInfo{
publicVariableInfo[]getVariableInfo(TagDatadata){
Stringtype=data.getAttributeString("type");
if(type==null)
type="java.lang.Object";
returnnewVariableInfo[]{
newVariableInfo(data.getAttributeString("id"),
type,
true,
VariableInfo.AT_BEGIN)
};
}
}
为剧本变量界说的tagextrainfo类的完整限制名必需在tag元素的tei-class子元素的TLD中声明。因而,DefineTei的tei-class元素像上面如许:
<tei-class>
org.apache.struts.taglib.bean.DefineTagTei
</tei-class>
标签协同操纵
标签经由过程共享对象完成互助。JSP手艺撑持两品种型的对象共享。
第一品种型请求在页面高低文中定名和贮存共享的对象(JSP页面和标签handler都能够会见的一种隐式对象)。要会见由另外一个标签创立和定名的对象,标签handler利用pageContext.getAttribute(name,scope)办法。
在第二种对象共享范例中,由一组嵌进标签中的核心标签handler创立的对象能够被一切外部标签handler会见。这类情势的对象共享的长处是它对对象利用公有定名空间,因而削减了潜伏的定名抵触。
要会见由核心标签创立的对象,标签handler必需起首用静态办法TagSupport.findAncestorWithClass(from,class)大概TagSupport.getParent办法取得其核心标签。在不克不及包管有特定的嵌进标签handler时应当利用前一个办法。一旦猎取了下级,那末标签handler就能够会见一切静态或静态创立的对象了。静态创立的对象是父标签的成员。公有对象也能够静态创立。这类对象能够用setValue办法贮存在标签handler中,并用getValue办法猎取它。
上面的例子展现了同时撑持定名的和公有对象体例共享对象的标签handler。在这个例子中,查询标签的handler反省名为connection的属性是不是已在doStartTag办法中设置。假如属性已设置,那末handler就从页面高低文中猎取毗连对象。不然,标签handler起首猎取核心标签的标签handler,然后从谁人handler中猎取毗连对象。
publicclassQueryTagextendsBodyTagSupport{
privateStringconnectionId;
publicintdoStartTag()
throwsJspException{
Stringcid=getConnection();
if(cid!=null){
//thereisaconnectionid,useit
connection=(Connection)pageContext.
getAttribute(cid);
}else{
ConnectionTagancestorTag=
(ConnectionTag)findAncestorWithClass(this,
ConnectionTag.class);
if(ancestorTag==null){
thrownewJspTagException("Aquerywithout
aconnectionattributemustbenested
withinaconnectiontag.");
}
connection=ancestorTag.getConnection();
}
}
}
由这个标签handler完成的查询标签能够以上面任何一种体例利用:
<tt:connectionid="con01"....>
...
</tt:connection>
<tt:queryid="balances"connection="con01">
SELECTaccount,balanceFROMacct_table
wherecustomer_number=<%=request.getCustno()%>
</tt:query>
<tt:connection...>
<x:queryid="balances">
SELECTaccount,balanceFROMacct_table
wherecustomer_number=<%=request.getCustno()%>
</x:query>
</tt:connection>
标签handler的TLD必需用上面声明指明connection属性是可选的:
<tag>
...
<attribute>
<name>connection</name>
<required>false</required>
</attribute>
</tag>
示例
本节中形貌的自界说标签展现了在开辟JSP使用程序时会常常碰到的两个成绩的办理办法:尽量削减JSP页面中的Java编程和包管全部使用程序的配合表面。在这个过程当中,展现了本章后面会商过的很多范例的标签。
迭代(Iteration)标签
构建依附于静态天生的数据的页面内容一般必要利用流把持剧本语句。经由过程将流把持逻辑转换到标签handler中,流把持标签削减了在JSP页面中必要的剧本量。
Strutslogic:iterate标签从贮存在JavaBeans组件中的汇合中猎取对象并将它们指定给剧本变量。标签的注释从剧本变量中提失信息。假如汇合中仍有元素,则iterate标签会再次对注释举行判别。
JSP页面
两个DukesBookstore使用程序页面catalog.jsp和showcart.jsp利用了logic:iterate标签以迭代对象的汇合。上面展现了catalog.jsp的一部分。JSP页面用bookDBbean汇合(由property属人命名)初始化iterate标签。iterate标签在对汇合上的每次迭代中设置book剧本变量。book变量的bookId属性作为另外一个剧本变量公然。两个变量的属性都用于静态天生一个包括到其他页面的图书目次信息的链接的表。
<logic:iteratename="bookDB"property="books"
id="book"type="database.BookDetails">
<bean:defineid="bookId"name="book"property="bookId"
type="java.lang.String"/>
<tr>
<tdbgcolor="#ffffaa">
<ahref="<%=request.getContextPath()%>
/bookdetails?bookId=<%=bookId%>">
<strong><jsp:getPropertyname="book"
property="title"/></strong></a></td>
<tdbgcolor="#ffffaa"rowspan=2>
<jsp:setPropertyname="currency"property="amount"
value="<%=book.getPrice()%>"/>
<jsp:getPropertyname="currency"property="format"/>
</td><tdbgcolor="#ffffaa"rowspan=2>
<ahref="<%=request.getContextPath()%>
/catalog?Add=<%=bookId%>">
<%=messages.getString("CartAdd")%>
</a></td></tr>
<tr>
<tdbgcolor="#ffffff">
<%=messages.getString("By")%><em>
<jsp:getPropertyname="book"
property="firstName"/>
<jsp:getPropertyname="book"
property="surname"/></em></td></tr>
</logic:iterate>
标签handler
Strutslogic:iterate标签的完成切合JSP版本1.1标准的请求,它必要扩大BodyTagSupport类。JSP版本1.2标准增加了简化迭代性地对注释判别的编程标签的功效(在不与注释交互的标签handler中形貌)。上面的会商是利用这些功效的完成。
logic:iterate标签以几种体例撑持汇合初始化:用作为标签属性而供应的汇合,大概用作为bean大概bean属性汇合而供应的汇合。我们的例子利用后一种办法。doStartTag中的年夜多半代码是关于构建关于一个对象汇合的迭代器的。办法起首反省是不是设置了handler的汇合属性,假如没有,则进一步反省bean和property属性。假如name和property属性都设置了,则doStartTag挪用利用JavaBean自省办法的工具办法来猎取汇合。一旦断定了汇合对象,办法就构建迭代器。
假如迭代器中另有元素,那末doStartTag就设置剧本变量的值为下一个元素,然后标明要对这个注释举行判别,不然就前往SKIP_BODY停止迭代。
在判别完注释后,doAfterBody办法提取注释内容并将它写进输入流。然后扫除注释内容对象以便为另外一次注释判别作筹办。假如迭代器还包括元素,那末doAfterBody就再次设置剧本变量的值为下一个元素并前往EVAL_BODY_AGAIN以标明应当再次对注释举行判别。如许会再次实行doAfterBody。假如没有残剩元素了,那末就前往SKIP_BODY停止这个历程。
publicclassIterateTagextendsTagSupport{
protectedIteratoriterator=null;
protectedObjectcollection=null;
protectedStringid=null;
protectedStringname=null;
protectedStringproperty=null;
protectedStringtype=null;
publicintdoStartTag()throwsJspException{
Objectcollection=this.collection;
if(collection==null){
try{
Objectbean=pageContext.findAttribute(name);
if(bean==null){
...throwanexception
}
if(property==null)
collection=bean;
else
collection=
PropertyUtils.
getProperty(bean,property);
if(collection==null){
...throwanexception
}
}catch
...catchexceptionsthrown
byPropertyUtils.getProperty
}
}
//Constructaniteratorforthiscollection
if(collectioninstanceofCollection)
iterator=((Collection)collection).iterator();
elseif(collectioninstanceofIterator)
iterator=(Iterator)collection;
...
}
//Storethefirstvalueandevaluate,
//orskipthebodyifnone
if(iterator.hasNext()){
Objectelement=iterator.next();
pageContext.setAttribute(id,element);
return(EVAL_BODY_AGAIN);
}else
return(SKIP_BODY);
}
publicintdoAfterBody()throwsJspException{
if(bodyContent!=null){
try{
JspWriterout=getPreviousOut();
out.print(bodyContent.getString());
bodyContent.clearBody();
}catch(IOExceptione){
...
}
}
if(iterator.hasNext()){
Objectelement=iterator.next();
pageContext.setAttribute(id,element);
return(EVAL_BODY_AGAIN);
}else
return(SKIP_BODY);
}
}
}
标签分外信息类
有关剧本变量的信息是在IterateTei标签分外信息类中供应的。剧本变量的名字和类以标签属性的情势传进,并用于到场VariableInfo机关函数。
publicclassIterateTeiextendsTagExtraInfo{
publicVariableInfo[]getVariableInfo(TagDatadata){
Stringtype=data.getAttributeString("type");
if(type==null)
type="java.lang.Object";
returnnewVariableInfo[]{
newVariableInfo(data.getAttributeString("id"),
type,
true,
VariableInfo.AT_BEGIN)};
}
}
模板标签库
模板供应了一种将使用程序中每屏幕城市呈现的共用元素与每屏幕城市改动的元素分别开来的办法。将一切大众元素一同放到一个文件中更简单举行保护,并能够增强一切屏幕的表面分歧性。它还使每屏幕的开辟更简单了,由于开辟者只需注意于该屏幕特定的那部份内容就能够了,模板会卖力大众部分。
模板是JSP页面,在每屏幕必要改动的中央有占位符。每个占位符称为模板的参数。比方,一个复杂的模板大概包括在天生的屏幕顶部的一个题目参数和JSP页面的注释参数以设定屏幕的定制内容。
模板利用嵌进的标签――definition、screen和parameter――界说屏幕界说表并利用标签将屏幕界说拔出到特定使用程序屏幕。
JSP页面
上面展现DukesBookstore例子的模板template.jsp。这一页面包含一个创立屏幕界说、并用insert标签将界说中的参数拔出使用程序屏幕的JSP页面。
<%@tagliburi="/tutorial-template.tld"prefix="tt"%>
<%@pageerrorPage="errorpage.jsp"%>
<%@includefile="screendefinitions.jsp"%><html>
<head>
<title>
<tt:insertdefinition="bookstore"
parameter="title"/>
</title></head>
<tt:insertdefinition="bookstore"
parameter="banner"/>
<tt:insertdefinition="bookstore"
parameter="body"/>
</body>
</html>
screendefinitions.jsp依据哀求属性selectedScreen创立屏幕界说:
<tt:definitionname="bookstore"
screen="<%=(String)request.
getAttribute("selectedScreen")%>">
<tt:screenid="/enter">
<tt:parametername="title"
value="DukesBookstore"direct="true"/>
<tt:parametername="banner"
value="/banner.jsp"direct="false"/>
<tt:parametername="body"
value="/bookstore.jsp"direct="false"/>
</tt:screen>
<tt:screenid="/catalog">
<tt:parametername="title"
value="<%=messages.getString("TitleBookCatalog")%>"
direct="true"/>
...
</tt:definition>
模板由Dispatcherservlet实例化。Dispatcher起首失掉所哀求的屏幕并将它贮存为哀求的属性。这是需要的,由于在向template.jsp转发哀求时,哀求URL不包括本来的哀求(如/bookstore3/catalog),而是反应转公布页面的路径(/bookstore3/template.jsp)。最初,servlet将哀求分发给template.jsp:
publicclassDispatcherextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,
HttpServletResponseresponse){
request.setAttribute("selectedScreen",
request.getServletPath());
RequestDispatcherdispatcher=
request.getRequestDispatcher("/template.jsp");
if(dispatcher!=null)
dispatcher.forward(request,response);
}publicvoiddoPost(HttpServletRequestrequest,
HttpServletResponseresponse){
request.setAttribute("selectedScreen",
request.getServletPath());
RequestDispatcherdispatcher=
request.getRequestDispatcher("/template.jsp");
if(dispatcher!=null)
dispatcher.forward(request,response);
}
}
标签handler
模板标签库包括四个标签handler――DefinitionTag、ScreenTag、ParameterTag和InsertTag,它们展现了协同操纵标签的利用。DefinitionTag、ScreenTag和ParameterTag构成了一组嵌进的标签handler,它们共享大众(public)和公有(private)对象。DefinitionTag创立由InsertTag利用的名为definition的大众对象,
在doStartTag中,DefinitionTag创立一个名为screens的大众对象,它包括屏幕界说的一个哈希表。屏幕界说包括屏幕标识符和一组与该屏幕相干联的参数。
publicintdoStartTag(){
HashMapscreens=null;
screens=(HashMap)pageContext.getAttribute("screens",
pageContext.APPLICATION_SCOPE);
if(screens==null)
pageContext.setAttribute("screens",newHashMap(),
pageContext.APPLICATION_SCOPE);
returnEVAL_BODY_INCLUDE;}
ScreenTag和ParameterTag用作为这些标签属性供应的笔墨添补屏幕界说表。表16-6显现了DukesBookstore使用程序的屏幕界说哈希表的内容。
表16-6屏幕界说
屏幕Id
题目
横幅
注释
/enter
DukesBookstore
/banner.jsp
/bookstore.jsp
/catalog
BookCatalog
/banner.jsp
/catalog.jsp
/bookdetails
BookDescription
/banner.jsp
/bookdetails.jsp
/showcart
ShoppingCart
/banner.jsp
/showcart.jsp
/cashier
Cashier
/banner.jsp
/cashier.jsp
/receipt
Receipt
/banner.jsp
/receipt.jsp
.
在doEndTag中,DefinitionTag创立Definition类的一个大众对象,依据在哀求中传送的URL从screens对象当选择一个屏幕界说,并用它初始化Definition对象。
publicintdoEndTag()throwsJspTagException{
try{
Definitiondefinition=newDefinition();
HashMapscreens=null;
ArrayListparams=null;
TagSupportscreen=null;
screens=(HashMap)
pageContext.getAttribute("screens",
pageContext.APPLICATION_SCOPE);
if(screens!=null)
params=(ArrayList)screens.get(screenId);
else
...
if(params==null)
...
Iteratorir=null;
if(params!=null)
ir=params.iterator();
while((ir!=null)&&ir.hasNext())
definition.setParam((Parameter)ir.next());
//putthedefinitioninthepagecontext
pageContext.setAttribute(
definitionName,definition);
}catch(Exceptionex){
ex.printStackTrace();
}returnEVAL_PAGE;
}
假如在哀求中传送的URL是/enter,那末Definition包括表16-6中第一行的项目:
题目
横幅
注释
DukesBookstore
/banner.jsp
/bookstore.jsp
URL/enter的界说如表16-7所示。这个界说指定Title参数的值DukesBookstore应当间接插队进到输入流中,可是Banner和Body的值应当静态地到场。
表16-7URL/enter的屏幕界说
参数名
参数值
isDirect
title
DukesBookstore
true
banner
/banner.jsp
false
body
/bookstore.jsp
false
InsertTag利用Definition将屏幕界说的参数拔出呼应中。在doStartTag办法中,它从页面高低文中猎取界说对象。
publicintdoStartTag(){
//getthedefinitionfromthepagecontext
definition=(Definition)pageContext.
getAttribute(definitionName);
//gettheparameter
if(parameterName!=null&&definition!=null)
parameter=(Parameter)definition.
getParam(parameterName);
if(parameter!=null)
directInclude=parameter.isDirect();
returnSKIP_BODY;
}
doEndTag办法拔出参数值。假如参数是间接的,那末就间接将它拔出呼应中,不然,哀求就被发送给参数,而其呼应则主动态地包括进全部呼应中。
publicintdoEndTag()throwsJspTagException{
try{
if(directInclude&¶meter!=null)
pageContext.getOut().print(parameter.getValue());
else{
if((parameter!=null)&&
(parameter.getValue()!=null))
pageContext.include(parameter.getValue());
}
}catch(Exceptionex){
thrownewJspTagException(ex.getMessage());
}
returnEVAL_PAGE;
}
怎样挪用标签handler?
Tag接口界说了标签handler与JSP页面的servlet之间的基础协定。它界说了性命周期和在碰到入手下手和停止标签时要挪用的办法。
JSP页面的servlet在挪用doStartTag之前挪用setPageContext、setParent和属性设置办法。JSP页面的servlet还包管在停止页面之前挪用标签handler的release。
上面是典范的标签handler办法挪用按次:
ATagt=newATag();
t.setPageContext(...);
t.setParent(...);
t.setAttribute1(value1);
t.setAttribute2(value2);
t.doStartTag();
t.doEndTag();
t.release();
BodyTag接口经由过程界说让标签handler会见其注释的其他办法扩大Tag。这个接口供应三个新办法:
・setBodyContent―创立注释内容并增加给taghandler
・doInitBody―在评价标签注释之前挪用
・doAfterBody―在评价标签注释以后挪用
典范的挪用按次为:
t.doStartTag();
out=pageContext.pushBody();
t.setBodyContent(out);
//performanyinitializationneededafterbodycontentissett.doInitBody();
t.doAfterBody();
//whiledoAfterBodyreturnsEVAL_BODY_BUFFEREDwe
//iteratebodyevaluation
...
t.doAfterBody();
t.doEndTag();
t.pageContext.popBody();
t.release();
C#是盗用了Java的源代码,仿照开发的,原因是Java是开源的啊,盗了也白盗,还有一点,开发C#语言的团队是就是开发Java语言的团队,是微软重金挖过去的啊 |
|