因胸联盟 发表于 2015-1-18 11:29:34

JAVA网站制作之创立 JSP 2.0 标志文件

你精通任何一门语言就最强大。现在来看,java的市场比C#大,C#容易入手,比较简单,java比较难js|创立懂得怎样利用JSP、JSTL和SQL来创立可重用的Web模板和数据库剧本

下载本文的源代码

标志文件是JavaServerPages(JSP)手艺最主要的新增功效之一,它同意Web开辟职员使用JSP语法创立自界说的标志库。JSP容器主动将JSP标志文件转换为Java代码,其历程与从JSP页通明地天生JavaServlet的历程不异。能够说标志文件埋没了创立自界说JSP标志库的庞大性。这类库可以在Web使用程序中重用,它们乃至在用于特定使用程序时也会供应明显的效益,由于自界说标志进步了Web页的可保护性。在浏览本文后,您将懂得怎样创立和利用标志文件和怎样将现有的页片断变更为标志文件。

JSP2.0界说了三个新的唆使语句(<%@tag%>、<%@attribute%>和<%@variable%>)和两个新的尺度操纵(<jsp:invoke>和<jsp:doBody>),它们只能在标志文件中利用。我们将在整篇文章中利用它们,而且您将懂得怎样使用加倍初级的标志文件特征,如“静态属性”、“片断属性”和“依据属人命名的变量”。当标志文件与JSP尺度标志库(JSTL)同时利用时,标志文件能够是一种功效壮大的工具,而JSTL引进了由JSP2.0和很多JSP操纵所接纳的表达式言语,包含一系列SQL标志。我们将利用JSTL和初级的JSP特征来创立标志文件,用于更新和查询数据库。

标志文件概述

JSP1.x同意Web开辟职员创立Java组件(称为标志处置程序),这些组件是经由过程自界说标志从JSP页举行挪用的。标志处置程序相似于之前的JavaServlet,由于您利用良多println()挪用来天生HTML内容,然后必需编译您的Java代码。JSP2.0的标志文件相似于JSP页,由于您利用JSP语法,然后JSP容器猎取您的JSP标志文件,剖析这些标志文件,天生Java标志处置程序,并主动编译它们。标志文件是从JSP页举行挪用的,JSP页利用与<prefix:tagFileName>形式相婚配的自界说标志。

为了使标志文件可以被JSP容器所辨认,标志文件必需利用.tag文件扩大名举行定名,而且必需被安排在您的Web使用程序的/WEB-INF/tags目次中大概/WEB-INF/tags的子目次中。假如您接纳这类部署办法,则不用创立任何标志库形貌器(TLD),由于JSP库是使用Java标志处置程序所实行的。您也能够将标志文件安排在.jar文件的/META-INF/tags目次中,其部署更简单,但在这类情形下,您必需创立TLD,而且必需在每次变动后从头对标志文件举行打包。

标志文件和JSP页利用几近不异的语法。您会注重到的第一个区分是新的<%@tag%>唆使语句,它同等于<%@page%>。这两个唆使语句具有类似的属性,但前者用于标志文件,尔后者只能用于JSP页中。标志文件其实不在一个独自的.tld文件中声明其属性和变量,而是利用<%@attribute%>和<%@variable%>唆使语句。当从JSP页挪用标志文件时,自界说标志能够具有主体(在<prefix:tagFileName>与</prefix:tagFileName>之间),该主体能够由标志文件使用<jsp:doBody>操纵来实行。您鄙人一节中将会看到这是怎样事情的。

利用标志文件取代页片断

为了具有可保护的Web页,很多经由优秀计划的JSP1.x使用程序利用了页片断,这些页片断是使用<jsp:include>或<%@include%>而包括在较年夜页面中的,而这不是在Web使用程序中重用JSP片断的幻想办法。与页包括办理计划分歧,标志文件公用于创立可重用的页片断库。本节对照了过期的JSP1.x办法的语法与JSP2.0标志文件的更好语法。

将被包括页变更为标志文件。让我们假定您具有一个名为container.jsp的页面,它使用<jsp:includepage="part.jsp"/>包括了另外一个名为part.jsp的页面。实行以下步骤,将part.jsp变更为标志文件。

第1步:挪动被包括页。
在您的使用程序的WEB-INF目次中,创立一个名为tags的子目次,并将part.jsp页挪动到WEB-INF/tags中。

第2步:重定名被包括页。
因为尺度的标志文件扩大名是.tag,您必需将part.jsp重定名为part.tag。

第3步:编纂标志文件。
翻开part.tag文件举行编纂,将<%@page%>唆使语句交换为相似的<%@tag%>唆使语句。假如碰到编译毛病,则大概必要举行其他一些小的修正。利用jspContext替换pageContext。

第4步:声明标志库。
在container.jsp的开首拔出<%@taglibprefix="tags"tagdir="/WEB-INF/tags"%>。

第5步:挪用标志文件。
在container.jsp中将<jsp:includepage="part.jsp"/>交换为<tags:part/>。

container.jsp(变更前)


<p>ContainerPage</p>

<jsp:includepage="part.jsp"/>


container.jsp(变更后)


<%@taglibprefix="tags"tagdir="/WEB-INF/tags"%>

<p>ContainerPage</p>

<tags:part/>


part.jsp(变更前)


<%@pagelanguage="java"%>

<p>IncludedPage</p>

<%=pageContext.getClass().getName()%>


part.tag(变更后)


<%@taglanguage="java"%>

<p>Invokedtag</p>

<%=jspContext.getClass().getName()%>


基于<jsp:include>和<%@include%>的示例。本示例的主页(main.jsp)利用<%@include%>唆使语句包括了两个页片断(header.jspf和footer.jspf)。主页还经由过程利用<jsp:include>来包括另外一个页面(content.jsp)。main.jsp页使用<jsp:param>尺度操纵,向被包括页供应了三个参数(a、b和c)。被包括的content.jsp页使用${param.a}、${param.b}和${param.c}输入三个参数的值。

main.jsp


<%@includefile="header.jspf"%>

<jsp:includepage="content.jsp">
<jsp:paramname="a"value="1"/>
<jsp:paramname="b"value="2"/>
<jsp:paramname="c"value="3"/>
</jsp:include>

<%@includefile="footer.jspf"%>


header.jspf


<p>Header</p>


footer.jspf


<p>Footer</p>


content.jsp


<p>IncludedContent</p>

<p>Parameters-${param.a},${param.b},${param.c}</p>


输入




基于标志文件的示例。本示例的JSP页(main.jsp)利用<%@taglib%>唆使语句来声明包括标志文件(wrapper.tag)的库,指出其前缀(tags)和创立标志文件的目次(/WEB-INF/tags)。main.jsp页利用<tags:wrapper>自界说标志来挪用wrapper.tag文件,该标志具有三个属性(a、b和c)和一些主体内容(<p>WrappedContent</p>)。注重,您在JSP页的<tags:wrapper>与</tags:wrapper>之间能够不利用任何剧本体例元素。剧本体例元素包含JSP1.x声明(<%!...%>)、JSP1.x表达式(<%=...%>)和scriptlet(<%...%>),而JSP2.0撑持一切这些元素。注重,标志文件能够象任何惯例JSP页一样利用剧本体例元素。实践上,假如您不喜好基于Java标志处置程序来创立JSP库,那末将Java代码从现有的JSP页移到标志文件中会是个不错的举措。这会使您的Javascriptlet能够被重用,并使您的Web页更容易读。JSP容器为您完成沉重的事情,它主动天生标志处置程序类。

wrapper.tag文件是后面示例中三个被包括页(header.jspf、footer.jspf和content.jsp)的替换品。标志文件利用<%@attribute%>唆使语句声明三个属性,并输入一个题目、一个页脚和属性的值(${a}、${b}和${c})。wrapper.tag文件使用新的<jsp:doBody>尺度操纵,实行main.jsp的<tags:wrapper>的主体。标志文件决意是不是实行和什么时候实行<tags:wrapper>的主体。假如wrapper.tag不利用<jsp:doBody>,则疏忽<tags:wrapper>的主体。标志文件还能够屡次利用<jsp:doBody>,以便屡次实行该主体。

main.jsp


<%@taglibprefix="tags"tagdir="/WEB-INF/tags"%>

<tags:wrappera="1"b="2"c="3">

<p>WrappedContent</p>

</tags:wrapper>


wrapper.tag


<%@tagbody-content="scriptless"%>
<%@attributename="a"required="true"%>
<%@attributename="b"required="true"%>
<%@attributename="c"required="true"%>

<p>Header</p>

<jsp:doBody/>

<p>Attributes-${a},${b},${c}</p>

<p>Footer</p>


输入




标志文件对照于<jsp:include>和<%@include%>。挪用标志文件的自界说标志具有比<jsp:include>与<jsp:param>的组合更严密的语法。自界说标志还能以天然的体例举行嵌套和缩进,使得代码易于浏览。独一大概感到方便的方面是一项限定,不同意您在挪用标志文件的自界说标志主体中利用剧本体例元素。思索到无剧本的Web页大概更容易于保护,实践上这大概是有益前提。假如您必需将JSP和Java代码夹杂在一同,则能够将Javascriptlet移到标志文件中。

<%@tag%>、<%@attribute%>和<%@variable%>唆使语句供应了更多的标志文件的优点:


属性声明使得标志文件的代码更容易读,由于您只需经由过程检察标志文件的题目便可找到属性的称号。关于被包括页,没有在页面的入手下手部分声明参数。假如您必需利用他人开辟的页面,而且没无为参数制造文档,则您大概必需剖析全部页面的源代码。


在默许情形下,一切的属性都是可选项。假如必要某个属性,您可使用<%@attributename="..."required="true"%>来指定它。在默许情形下,挪用标志文件的自界说标志能够包括无剧本的JSP代码。假如标志文件没有利用<jsp:doBody>,您应当利用<%@tagbody-content="empty"%>指定该标志文件疏忽主体内容。这类声明避免不测利用在<prefix:tagFileName>与</prefix:tagFileName>之间JSP内容。在这类情形下,应当使用如<prefix:tagFileName/>的空标志来挪用标志文件。经由过程唆使所需的属性和是不是利用主体内容,您能够避免良多罕见毛病,削减了调试JSP页所消费的工夫。对被包括的JSP页不供应这类声明撑持。


也能够利用相似<%@attributetype="className"%>的语句来指定属性的范例。属性值将会被主动转换为指定范例,假如转换失利,会呈现一个毛病。假如是被包括页,一切的参数都是字符串,必需编写一切必须的转换。


新的<%@variable%>唆使语句供应了对JSP容器的提醒,该容器主动实行诸如JSP变量的导出和同步等义务,这有助于被挪用标志文件与挪用页之间的通讯。我们稍后将在本文中懂得它是怎样事情的。假如是被包括的JSP页,必需手动完成页间的通讯,这一般必要更多的编程操纵。


<%@attribute%>和<%@variable%>唆使语句撑持那些在被包括JSP页中不克不及利用的特征,如在java.util.Map中搜集的静态属性、暗示JSP片断的属性和称号由属性所指定的变量。下一节中的示例利用了这些特征。

利用初级JSP2.0特征

以下示例显现怎样开辟JSP标志文件的真正功效。您将懂得怎样处置静态属性、怎样将变量作为输入参数利用、怎样利用属性来定名变量和怎样利用属性将JSP片断传送给标志文件。Then,wellusetheseadvancedJSPfeaturestobuildanothersetoftagfilesthatqueryandupdateadatabaseusingtheJSPexpressionlanguagewithinSQLstatements.

在标志文件中处置静态属性。本示例包括一个标志文件(dynamicAttr.tag),该标志文件承受静态属性和使用<%@attribute>唆使语句所声明的几个其他属性(listTag、itemTag和separator)。一个JSP页(dynamicAttr.jsp)利用<demo:dynamicAttr>标志来挪用标志文件。被声明的属性与静态属性能够夹杂在一同,由于属性的按次其实不主要。

在默许情形下,标志文件只承受被声明的属性。为了可以撑持静态属性,标志文件必需利用<%@tagdynamic-attributes="varName"%>,供应一个坚持java.util.Map中一切静态属性的变量名。在我们的示例中,该变量被定名为attrMap。dynamicAttr.tag文件使用JSTL的<c:forEach>操纵对attrMap的项目举行迭代,使用${attr.key}和${attr.value}取得每一个属性的称号和值。

假如您检察输入,会发明六个静态属性(first、second、…sixth)不是以dynamicAttr.jsp中<demo:dynamicAttr>标志所指定的按次而取得的。这类情形是由于java.util.Map实行把持着其项目标按次。因而,必需对标志文件举行筹办,以便以恣意按次处置其静态属性。

dynamicAttr.tag文件利用<jsp:element>尺度操纵,用于天生那些在运转时取得其称号的HTML元素。这类新的JSP2.0特征与静态属性有关,但我们在本例中利用它来天生HTML列表(listTag为“ul”,而itemTag为“li”)。

dynamicAttr.tag


<%@tagdynamic-attributes="attrMap"%>
<%@attributename="listTag"required="true"%>
<%@attributename="itemTag"required="true"%>
<%@attributename="separator"required="true"%>
<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

<p>DynamicAttributes:</p>
<jsp:elementname="${listTag}">
<c:forEachvar="attr"items="${attrMap}">
<jsp:elementname="${itemTag}">
${attr.key}${separator}${attr.value}
</jsp:element>
</c:forEach>
</jsp:element>


dynamicAttr.jsp


<%@taglibprefix="demo"tagdir="/WEB-INF/tags/demo"%>

<demo:dynamicAttrseparator="="
first="1"second="2"third="3"
listTag="ul"itemTag="li"
fourth="4"fifth="5"sixth="6"/>


输入




从标志文件导出变量到JSP页。JSTL的<c:set>标志同意您在四种JSP的局限(页面、哀求、会话和使用程序)中创立和变动变量。JSP页与那些从JSP页所挪用的标志文件共享哀求、会话和使用程序局限。页面局限是<c:set>的默许局限,它其实不共享。因而,您能够将那些在哀求、会话和使用程序局限内创立的变量看做“全局变量”,而将那些在页面局限内创立的变量看做“当地变量”。

因为每一个标志文件都有本人的页面局限,在被挪用的标志文件中不克不及会见挪用页的当地变量,反之亦然。JSP页可使用标志属性和全局变量,将参数传送到被挪用的标志。关于每一个属性,JSP容器在标志文件的页面局限内创立一个当地变量,同意您利用${attributeName}布局来取得属性的值。因而,标志属性充任由值所传送的参数,而全局变量充任由援用所传送的参数。假如标志文件变动了全局变量的值,则这类变动将影响JSP页。

标志文件可使用<%@variable%>唆使语句将其当地变量“导出”到挪用页。能够在标志文件中利用<%@variablename-given="..."%>指定变量的称号,而JSP页也能够供应变量名,我们将在varAttr.jsp示例中看到这类情形。变量的范例能够使用<%@variablevariable-class="..."%>来唆使。

当使用<%@variable%>在标志文件中声明变量后,您必需利用<c:set>来设置该变量的值。JSP容器使用在JSP页中给定的称号创立另外一个变量,而这第二个变量是使用标志文件中的响应变量值举行初始化的。变动JSP页的变量值不会影响标志文件中的响应变量。可是,JSP容器依据<%@variable%>的局限属性来更新JSP页的变量,该属性多是AT_BEGIN、NESTED或AT_END。

假如scope是AT_END,则使用标志文件实行以后的标志文件变量值来初始化JSP页的变量。假如scope是AT_BEGIN,则在<jsp:doBody>之前、在每一个<jsp:invoke>之前和在标志文件的实行停止时更新JSP页的变量。假如scope是NESTED,则仅在<jsp:doBody>之前和每一个<jsp:invoke>之前使用标志文件变量的值来更新JSP变量。在标志文件实行后,假如是NESTED的情形,则将JSP变量恢复到它在挪用标志文件之前所具有的值。

为了更好地舆解变量怎样事情,让我们在一个示例中来利用它们,该示例包含一个标志文件(varScope.tag)、一个JSP页(varScope.jsp)和几个片断(varScopeRow.tagf、varScopeHeader.jspf、varScopeFooter.jspf和varScopeRow.jspf)。这些片断只用于创立一个HTML表。我们在本示例中研讨标志文件变量时,必需利用<%@include%>将逻辑与表达相分别。在多半情形下,利用标志文件举行表达是最好的办理计划,但在本次情形中,分外的标志文件会搅扰我们要研讨的变量“导出”机制。

标志文件利用了一个“全局”变量(GV)、一个未声明的“当地”变量(LV)和三个使用<%@variable%>所声明的变量(BV、NV和EV)。varScope.tag文件使用“TAGA”对这些变量举行初始化,然后利用<jsp:doBody>,最初将一切变量的值都改成“TAGB”字符串。varScope.jsp页使用“JSPA”对其本人的一系列变量举行初始化,然后使用<demo:varScope>挪用标志文件,在<demo:varScope>的主体内将变量的值改成“JSPB”。其了局输入包括在源代码的前面。

varScope.tag


<%@variablename-given="BV"scope="AT_BEGIN"%>
<%@variablename-given="NV"scope="NESTED"%>
<%@variablename-given="EV"scope="AT_END"%>
<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

<c:setvar="tagPhase"value="TAG:atbegin"/>
<%@includefile="varScopeRow.tagf"%>

<c:setvar="GV"value="TAGA"scope="request"/>
<c:setvar="LV"value="TAGA"/>
<c:setvar="BV"value="TAGA"/>
<c:setvar="NV"value="TAGA"/>
<c:setvar="EV"value="TAGA"/>

<c:setvar="tagPhase"value="TAG:beforedoBody"/>
<%@includefile="varScopeRow.tagf"%>

<jsp:doBody/>

<c:setvar="tagPhase"value="TAG:afterdoBody"/>
<%@includefile="varScopeRow.tagf"%>

<c:setvar="GV"value="TAGB"scope="request"/>
<c:setvar="LV"value="TAGB"/>
<c:setvar="BV"value="TAGB"/>
<c:setvar="NV"value="TAGB"/>
<c:setvar="EV"value="TAGB"/>

<c:setvar="tagPhase"value="TAG:atend"/>
<%@includefile="varScopeRow.tagf"%>


varScopeRow.tagf


<tr>
<tdwidth="25%">${tagPhase}</td>
<c:setvar="allEqual"value=
"${LV==GVandLV==BVandLV==NVandLV==EV}"/>
<c:iftest="${allEqual}">
<tdalign="center"width="75%"colspan="5">
<i>${LV!=null?LV:"null"}</i>
</td>
</c:if>
<c:iftest="${!allEqual}">
<tdalign="center"width="15%">
${GV!=null?GV:"null"}
</td>
<tdalign="center"width="15%">
${LV!=null?LV:"null"}
</td>
<tdalign="center"width="15%">
${BV!=null?BV:"null"}
</td>
<tdalign="center"width="15%">
${NV!=null?NV:"null"}
</td>
<tdalign="center"width="15%">
${EV!=null?EV:"null"}
</td>
</c:if>
</tr>


varScope.jsp


<%@taglibprefix="demo"tagdir="/WEB-INF/tags/demo"%>
<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

<%@includefile="varScopeHeader.jspf"%>

<c:setvar="GV"value="JSPA"scope="request"/>
<c:setvar="LV"value="JSPA"/>
<c:setvar="BV"value="JSPA"/>
<c:setvar="NV"value="JSPA"/>
<c:setvar="EV"value="JSPA"/>

<c:setvar="jspPhase"value="JSP:beforestarttag"/>
<%@includefile="varScopeRow.jspf"%>

<demo:varScope>

<c:setvar="jspPhase"value="JSP:afterstarttag"/>
<%@includefile="varScopeRow.jspf"%>

<c:setvar="GV"value="JSPB"scope="request"/>
<c:setvar="LV"value="JSPB"/>
<c:setvar="BV"value="JSPB"/>
<c:setvar="NV"value="JSPB"/>
<c:setvar="EV"value="JSPB"/>

<c:setvar="jspPhase"value="JSP:beforeendtag"/>
<%@includefile="varScopeRow.jspf"%>

</demo:varScope>

<c:setvar="jspPhase"value="JSP:afterendtag"/>
<%@includefile="varScopeRow.jspf"%>

<%@includefile="varScopeFooter.jspf"%>


varScopeHeader.jspf


<tableborder="1">

<tr>
<thwidth="25%">

</th>
<thalign="center"width="15%">
GV<br>GlobalVar<br>inRequest<br>Scope
</th>
<thalign="center"width="15%">
LV<br>LocalVar<br>Not<br>Declared
</th>
<thalign="center"width="15%">
BV<br>TagVar<br>Scope:<br>AT_BEGIN
</th>
<thalign="center"width="15%">
NV<br>TagVar<br>Scope:<br>NESTED
</th>
<thalign="center"width="15%">
EV<br>TagVar<br>Scope:<br>AT_END
</th>
</tr>


varScopeFooter.jspf


</table>


varScopeRow.jspf


<tr>
<tdwidth="25%">${jspPhase}</td>
<c:setvar="allEqual"value=
"${LV==GVandLV==BVandLV==NVandLV==EV}"/>
<c:iftest="${allEqual}">
<tdalign="center"width="75%"colspan="5">
<i>${LV!=null?LV:"null"}</i>
</td>
</c:if>
<c:iftest="${!allEqual}">
<tdalign="center"width="15%">
${GV!=null?GV:"null"}
</td>
<tdalign="center"width="15%">
${LV!=null?LV:"null"}
</td>
<tdalign="center"width="15%">
${BV!=null?BV:"null"}
</td>
<tdalign="center"width="15%">
${NV!=null?NV:"null"}
</td>
<tdalign="center"width="15%">
${EV!=null?EV:"null"}
</td>
</c:if>
</tr>


输入




利用属性为变量供应称号。后面的示例显现了怎样利用变量,那些变量的称号是由标志文件给定的。上面的示例具有一个标志文件(varAttr.tag),它创立一个变量,该变量称号由JSP页(varAttr.jsp)以标志属性的值(v)供应。为了可以操纵此变量,标志文件利用<%@variablename-from-attribute="v"...alias="a"...%>界说了一一般名(a)。

varAttr.tag文件使用<c:setvar="a"value="..."/>设置变量的值,使用${v}输入变量的称号,并使用${a}输入变量的值。varAttr.jsp页使用<demo:varAttrv="x"/>挪用标志文件,并利用定名为x的变量。注重,JSP容器主动创立x变量,将其设为a的值,即123。

varAttr.tag


<%@attributename="v"required="true"%>
<%@variablename-from-attribute="v"
variable-class="java.lang.Long"
alias="a"scope="AT_END"%>
<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

<c:setvar="a"value="${123}"/>

<p>TAG:${v}=${a}</p>


varAttr.jsp


<%@taglibprefix="demo"tagdir="/WEB-INF/tags/demo"%>

<demo:varAttrv="x"/>

<p>JSP:x=${x}</p>


输入




从标志文件挪用JSP片断。今朝您已懂得标志文件撑持两种属性范例:复杂声明的属性和静态属性。第三品种型称为片断属性。本示例的JSP页(fragmentAttr.jsp)使用<demo:fragmentAttr>挪用标志文件(fragmentAttr.tag),供应了两个复杂的属性(attr1和attr2)和一个片断属性(template)。全体三个属性都是使用<%@attribute%>在标志文件中声明的,但只要template使用fragment="true"被声明为片断属性。

fragmentAttr.jsp页利用<jsp:attribute>和<jsp:body>尺度操纵,分离界说了两个使用<jsp:invoke>和<jsp:doBody>从标志文件中挪用的JSP片断。别的,标志文件使用<%@variable%>声了然一个嵌套变量(data)。该变量的值由标志文件使用<c:set>举行设置,而两个JSP片断使用${data}输入该变量的值。/P>

fragmentAttr.tag


<%@attributename="template"fragment="true"%>
<%@attributename="attr1"%>
<%@attributename="attr2"%>
<%@variablename-given="data"scope="NESTED"%>
<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

<c:setvar="data"value="${attr1}"/>
<jsp:invokefragment="template"/>

<c:setvar="data"value="${attr1}-${attr2}"/>
<jsp:doBody/>

<c:setvar="data"value="${attr2}"/>
<jsp:invokefragment="template"/>

<c:setvar="data"value="${attr2}-${attr1}"/>
<jsp:doBody/>


fragmentAttr.jsp


<%@taglibprefix="demo"tagdir="/WEB-INF/tags/demo"%>

<demo:fragmentAttrattr1="value1"attr2="value2">
<jsp:attributename="template">
<p>Template:${data}</p>
</jsp:attribute>
<jsp:body>
<p>BodyContent:${data}</p>
</jsp:body>
</demo:fragmentAttr>


输入




利用标志文件更新和查询数据库

在开辟庞大的企业使用程序时,良多人更喜好利用企业JavaBean(EJB)手艺,让使用服务器来办理对象可延续性。其别人大概更喜好利用Java数据库毗连(JDBC)尺度API,以便手动地优化数据库会见。这些办理计划大概不合适于复杂的由数据库撑持的网站,这类网站只需利用JSP尽量快地举行原型开辟。假如您只必要查询和更新一个复杂的数据库,则供应数据库会见特征的标志库多是最好的办理计划。

JSTL具有一系列复杂的SQL标志,我们将在以下的示例中利用它们。不要间接从您的页面挪用JSTLSQL标志,而利用标志文件将表达与数据库会见剧本相分别是个好举措。这类分别同意您今后可以便利地切换到另外一个数据库毗连办理计划,以便进步使用程序的功能和可伸缩性。

JSTL不是独一供应数据库会见特征的标志库。Oracle使用程序开辟框架(ADF)供应了一个称为商务组件数据标志的JSP库,它包括一系列与数据库相干的加倍初级的JSP标志。注重,ADF特征集的局限更普遍,使得OracleADF合适于复杂的和庞大的使用程序。OracleADF与JDeveloper10g绑定在一同,后者具有效于ADF的可视计划工具。

以下的六个示例创立一个表、拔出三行、更新一行、删除另外一行、实行一些查询再删除该表。这统统都是使用通用标志文件完成的,这些标志文件不依附于表的布局。

第1步:创立表。本示例的JSP页(create.jsp)挪用标志文件(create.tag)来创立表,该表的布局以<db:create>自界说标志的主体内容供应。表的属性指定了表名(People)。在创立表后,JSP页输入一条动静,关照用户该操纵已完成:


<db:createtable="People">
userIDINTEGER,
nameVARCHAR2(60),
emailVARCHAR2(60)
</db:create>

<p>Tablecreated.</p>


create.tag文件包括一个标志片断(init.tagf),该片断使用JSTL的<sql:setDataSource>标志,在使用程序局限内设置一个名为tags_db_dataSource的javax.sql.DataSource变量。只要当该变量还没有存在,而且将要与JSTL的<sql:update>标志(该标志实行其主体中的SQL语句)一同在标志文件中利用时,才会创立该变量。create.tag文件静态地创立CREATETABLE语句,使用${table}猎取表名,并使用<jsp:doBody>拔出表的布局:


<sql:updatedataSource="${tags_db_dataSource}">
CREATETABLE${table}(<jsp:doBody/>)
</sql:update>


为了运转示例,您必需设置一个名为dbtags的数据源。在Web使用程序的形貌器(web.xml)中声了然对该资本的援用:


<resource-ref>
<res-ref-name>jdbc/dbtags</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>


init.tagf片断从一个初始化参数那边取得资本的路径,这个初始化参数也是在web.xml中界说的:


<context-param>
<param-name>tags_db_dataSource</param-name>
<param-value>jdbc/dbtags</param-value>
</context-param>


假如您要利用另外一个数据源,只需在web.xml文件中将dbtags交换为您的数据源称号。

init.tagf


<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglibprefix="sql"uri="http://java.sun.com/jsp/jstl/sql"%>

<c:iftest="${applicationScope.tags_db_dataSource==null}">
<sql:setDataSource
dataSource="${initParam.tags_db_dataSource}"
var="tags_db_dataSource"scope="application"/>
</c:if>


create.tag


<%@tagbody-content="scriptless"%>
<%@attributename="table"required="true"%>
<%@includefile="init.tagf"%>

<sql:updatedataSource="${tags_db_dataSource}">
CREATETABLE${table}(<jsp:doBody/>)
</sql:update>


create.jsp


<%@taglibprefix="db"tagdir="/WEB-INF/tags/db"%>

<db:createtable="People">
userIDINTEGER,
nameVARCHAR2(60),
emailVARCHAR2(60)
</db:create>

<p>Tablecreated.</p>


第2步:拔出。在您具有表以后,可使用<db:insert>标志每次拔出一行,该标志使用以下语法挪用标志文件(insert.tag):


<db:inserttable="..."column1="value1"column2="value2".../>


一个示例JSP页(insert.jsp)利用<db:insert>将三行拔出到People表中。在每次挪用时,标志文件利用以下语法创立和实行一条SQL语句:


INSERTINTOtable(column1,column2,...)VALUES(value1,value2,...)


列名和值被指定为静态属性,因此<db:insert>可用于任何表,而不管表的列是怎样定名的。标志文件利用<c:forEach>,对java.util.Map实例(columnAttr)的项目举行迭代,该实例持有<db:insert>的静态属性。每一个静态属性的称号暗示一个列名,而且使用${v_entry.key}而取得。标志文件使用${v_entry.value}取得那些必需被拔出到表中的值。

在<sql:update>的主体内,标志文件创立一个列名的列表(v_columnNames)和另外一个包括参数标记的列表(v_paramMarkers)。JSTL的<sql:param>标志与传送SQL参数值的<sql:update>合作。在实行了不发生任何输入的<c:forEach>轮回以后,标志文件使用以下语句发生SQL语句


INSERTINTO${table}(${v_columnNames})VALUES(${v_paramMarkers})


当insert.jsp挪用标志文件时,<sql:update>标志求出其主体所得的值


INSERTINTOPeople(userID,name,email)VALUES(?,?,?)


然后,<sql:update>利用JDBCAPI并传送由<sql:param>所发送的参数值,实行以上的SQL语句。注重,列及其响应的值大概以分歧的按次呈现,由于它们是从java.util.Map实例中检索出来的。因而,我们必需确保SQL语句不依附于列的按次。

insert.tag


<%@tagbody-content="empty"dynamic-attributes="columnAttr"%>
<%@attributename="table"required="true"%>
<%@includefile="init.tagf"%>

<c:setvar="v_columnNames"value=""/>
<c:setvar="v_paramMarkers"value=""/>
<c:setvar="v_separator"value=""/>
<sql:updatedataSource="${tags_db_dataSource}">
<c:forEachvar="v_entry"items="${columnAttr}">
<sql:paramvalue="${v_entry.value}"/>
<c:setvar="v_columnNames"
value="${v_columnNames}${v_separator}${v_entry.key}"/>
<c:setvar="v_paramMarkers"
value="${v_paramMarkers}${v_separator}${?}"/>
<c:setvar="v_separator"value=","/>
</c:forEach>
INSERTINTO${table}(${v_columnNames})
VALUES(${v_paramMarkers})
</sql:update>


insert.jsp


<%@taglibprefix="db"tagdir="/WEB-INF/tags/db"%>

<db:inserttable="People"userID="1"name="JohnSmith"
email="JohnSmith@company.com"/>

<db:inserttable="People"userID="2"name="MarkJohnson"
email="MarkJohnson@company.com"/>

<db:inserttable="People"userID="3"name="BillDavis"
email="BillDavis@company.com"/>

<p>Rowsinserted.</p>


第3步:更新。update.jsp页利用<db:update>来变动那些使用insert.jsp拔出的行中的某一行的email值。update.tag文件相似于insert.tag,但此时JSTL的<sql:update>标志用于实行UPDATE语句:


UPDATEtableSETcolumn1=value1,column2=value2,...WHERE...


利用以下语法将列及其值指定为静态属性:


<db:updatetable="..."column1="value1"column2="value2"...
where="..."/>


标志文件利用静态属性来创立一个包括column=?布局的列表(v_setList)。使用后面示例中的<sql:param>,将列值传送到<sql:update>。然后,update.tag使用以下语句天生SQL语句



UPDATE${table}SET${v_setList}WHERE${where}


当update.jsp挪用标志文件时,<sql:update>标志求出其主体所得的值


UPDATEPeopleSETemail=?WHEREuserID=2


分歧于每次只能用于拔出一行的<db:insert>标志,<db:update>标志可用于在单次挪用中更新多行。

update.tag资本

利用以下资本来测试这些示例,并懂得有关JSP2.0标志文件和JSTL中心和SQL标志的更多信息。

下载源代码
tagfiles_src.zip文件包括了本文中的示例。为运转这些示例,您必要J2SE、J2EE1.4使用服务器、JSTL1.1和数据库服务器。

下载OC4J10g
OracleApplicationServerContainersforJ2EE10g充实实行了包含JSP2.0在内的J2EE1.4标准。你可使用OC4J10g(10.0.3)来测试这些示例。它可用于一切次要的数据库服务器―固然―包含Oracle数据库。

下载JSTL1.1
在部署示例之前,下载JSTL并将jstl.jar和standard.jar复制到Web使用程序的WEB-INF/lib目次。别的,不要健忘设置dbtags数据源,并确保可使用准确的数据库驱动程序。

浏览JSP2.0标准
JSP2.0标准中有整整一章专门针对标志文件(“第一部分:JSP章节。8标志文件”)。JSP2.0所推出的新的尺度操纵在另外一章(“第一部分:JSP章节。5尺度操纵”)中予以申明。

浏览JSTL1.1标准
JSTL标准申明了本文示例中所利用的<c:set>、<c:if>、<c:forEach>、<sql:setDataSource>、<sql:query>、<sql:update>和<sql:param>标志。

相干文章与下载

怎样:向JDeveloper10g增加自界说的JSP标志库


OracleJDeveloper10g

JSP示例代码

教程:懂得JSP2.0的新特征,“标志文件”模块



<%@tagbody-content="empty"dynamic-attributes="columnAttr"%>
<%@attributename="table"required="true"%>
<%@attributename="where"required="false"%>
<%@includefile="init.tagf"%>

<c:setvar="v_setList"value=""/>
<c:setvar="v_separator"value=""/>
<sql:updatedataSource="${tags_db_dataSource}">
<c:forEachvar="v_entry"items="${columnAttr}">
<sql:paramvalue="${v_entry.value}"/>
<c:setvar="v_setList"
value="${v_setList}${v_separator}${v_entry.key}=?"/>
<c:setvar="v_separator"value=","/>
</c:forEach>
UPDATE${table}SET${v_setList}
<c:iftest="${!emptywhere}">WHERE${where}</c:if>
</sql:update>


update.jsp


<%@taglibprefix="db"tagdir="/WEB-INF/tags/db"%>

<db:updatetable="People"
email="markj@company.com"where="userID=2"/>

<p>Rowupdated.</p>


第4步:删除。以下的标志文件(delete.tag)可用于删除一行或多行,它位于delete.jsp页中。

delete.tag


<%@tagbody-content="empty"%>
<%@attributename="table"required="true"%>
<%@attributename="where"required="false"%>
<%@includefile="init.tagf"%>

<sql:updatedataSource="${tags_db_dataSource}">
DELETEFROM${table}
<c:iftest="${!emptywhere}">WHERE${where}</c:if>
</sql:update>


delete.jsp


<%@taglibprefix="db"tagdir="/WEB-INF/tags/db"%>

<db:deletetable="People"where="userID=1"/>

<p>Rowdeleted.</p>


第5步:选择。下一个标志文件(select.tag)利用JSTL的<sql:query>标志来实行SELECT语句。<db:select>的语法包含鄙人面:


<db:selectvar="row"table="..."columns="..."
where="..."groupBy="..."having="..."orderBy="...">

processtheresultofthequery,onerowatatime

</db:select>


<db:select>标志创立和实行以下的SQL语句,其子句被指定为标志的属性。


SELECTcolumnsFROMtableWHERE...
GROUPBY...HAVING...ORDERBY...


当<db:select>呈现在JSP页中时,使用select.tag的<jsp:doBody>操纵为每行挪用它的主体。JSP页从一个由标志文件与JSTL所创立的java.util.Map中猎取行数据。比方,以后行的值能够使用相似${row.userID}、${row.name}和${row.email}的JSP布局而取得,此时假定JSP页挪用的标志文件指定应当将持无数据的变量定名为row:


<db:selectvar="row"table="People"columns="*">
${row.userID}...${row.name}...${row.email}
</db:select>


select.jsp页两次挪用了标志文件。起首它利用<db:select>来迭代干系表的行,天生一个HTML表,然后JSP页利用<db:select>来盘算People表的行数。

select.tag


<%@tagbody-content="scriptless"%>
<%@attributename="var"required="true"%>
<%@variablename-from-attribute="var"
alias="v_row"scope="NESTED"%>
<%@attributename="table"required="true"%>
<%@attributename="columns"required="false"%>
<%@attributename="where"required="false"%>
<%@attributename="groupBy"required="false"%>
<%@attributename="having"required="false"%>
<%@attributename="orderBy"required="false"%>
<%@includefile="init.tagf"%>

<sql:querydataSource="${tags_db_dataSource}"var="v_result">
SELECT${emptycolumns?"*":columns}FROM${table}
<c:iftest="${!emptywhere}">WHERE${where}</c:if>
<c:iftest="${!emptygroupBy}">GROUPBY${groupBy}</c:if>
<c:iftest="${!emptyhaving}">HAVING${having}</c:if>
<c:iftest="${!emptyorderBy}">ORDERBY${orderBy}</c:if>
</sql:query>

<c:forEachvar="v_row"items="${v_result.rows}">
<jsp:doBody/>
</c:forEach>


select.jsp


<%@taglibprefix="db"tagdir="/WEB-INF/tags/db"%>
<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

<tableborder="2"cellspacing="1"cellpadding="3">
<tr>
<th>UserID</th>
<th>Name</th>
<th>Email</th>
</tr>
<db:selectvar="row"table="People"orderBy="name">
<tr>
<td>${row.userID}</td>
<td>${row.name}</td>
<td>${row.email}</td>
</tr>
</db:select>
</table>

<db:selectvar="c"table="People"columns="count(*)asn">
<p>${c.n}people.</p>
</db:select>


输入




第6步:删除表。假如您但愿再次实行JSP示例,则必需使用drop.jsp页删除表,该页利用了drop.tag文件。

drop.tag


<%@tagbody-content="scriptless"%>
<%@attributename="table"required="true"%>
<%@includefile="init.tagf"%>

<sql:updatedataSource="${tags_db_dataSource}">
DROPTABLE${table}
</sql:update>


drop.jsp


<%@taglibprefix="db"tagdir="/WEB-INF/tags/db"%>

<db:droptable="People"/>

<p>Tabledropped.</p>


结论

标志文件是Web开辟职员所必要的一种易于利用的办理计划,用于创立自界说标志库。从Java标志处置程序到JSP标志文件的变化相似于几年前呈现的从Servlet到JSP的变化。在开辟JavaWeb使用程序时,年夜部分静态内容如今是由JSP天生的,但Servlet仍旧用作JSP的一种底层手艺,而且在有些情形下Servlet比JSP更合用。一样,Java标志处置程序仍旧必要作为标志文件的一种底层手艺,用于创立庞大的标志库,如JSTL。可是,年夜多半标志库将利用标志文件来创立,由于标志文件简化了开辟历程。


--------------------------------------------------------------------------------
AndreiCioroianu(devtools@devsphere.com)是Devsphere(www.devsphere.com)的开创人,这是一家Java框架、XML征询和Web开辟服务的供给商。AndreiCioroianu撰写了良多Java文章,由ONJava、JavaWorld和JavaDevelopersJournal宣布。他还与他人合著了JavaXMLProgrammersReference和ProfessionalJavaXML两本书(均由WroxPress出书)。

唉!都是钱闹的1.Swing和.net开发比较------从市场份额看.net开发主要占据大部分的中小型和中型的的桌面开发,原因是它封装了很多工具

柔情似水 发表于 2015-1-21 08:20:48

接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。

山那边是海 发表于 2015-1-27 21:40:09

是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言

变相怪杰 发表于 2015-1-30 19:04:25

在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。

飘飘悠悠 发表于 2015-2-6 15:06:09

是一种使用者不需花费很多时间学习的语言

老尸 发表于 2015-2-6 16:40:52

是一种为 Internet发展的计算机语言

深爱那片海 发表于 2015-2-17 07:57:50

我大二,Java也只学了一年,觉得还是看thinking in java好,有能力的话看英文原版(中文版翻的不怎么好),还能提高英文文档阅读能力。

分手快乐 发表于 2015-2-23 09:57:21

http://www.jdon.com/去下载,或到同济技术论坛的服务器ftp://nro.shtdu.edu.cn去下,安装上有什么问题,可以到论坛上去提问。

admin 发表于 2015-3-4 05:02:24

J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。

爱飞 发表于 2015-3-11 17:16:54

还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。

只想知道 发表于 2015-3-12 15:44:48

是一种使网页(Web Page)产生生动活泼画面的语言

精灵巫婆 发表于 2015-4-3 03:18:00

至于JDBC,就不用我多说了,你如果用java编过存取数据库的程序,就应该很熟悉。还有,如果你要用Java编发送电子邮件的程序,你就得看看Javamail 了。
页: [1]
查看完整版本: JAVA网站制作之创立 JSP 2.0 标志文件