JSTL詳解(九)
9.9? 完整示例
在這一小節(jié)中,將修改在第三章中曾經(jīng)給出的
Struts
框架示例,以
Struts
框架和
JSTL
的協(xié)同
對于第三章的示例,要將 JSTL 整合進(jìn)去,需要做以下幾步工作。
(
1
)
( 1 )修改原先的 web.xml 使其作為 Servlet2.4 的實現(xiàn)。
( 3 )修改 JSP 顯示頁面,整合 JSTL 和 Struts 標(biāo)簽庫一起工作。
9.9.1? 下載 JSTL 并配置
可以從 http://java.sun.com/products/jsp/jstl 網(wǎng)址中下載 JSTL1.1 的最新版本。要使用這些標(biāo)簽庫需要做 3 個步驟的工作。
( 1 )將下載的 jstl.jar 放置到 Web 應(yīng)用的 WEB-INF 的 lib 目錄下。
( 2 )將下載的 TLD 文件放置到 Web 應(yīng)用的 WEB-INF 目錄下。
( 3 )在需要使用的 JSP 頁面中聲明該標(biāo)簽庫。
9.9.2? 修改 web.xml 使其作為 Servlet2.4 的實現(xiàn)
在第三章的示例中所給出的 web.xml 是 Servlet2.3 規(guī)范的,因此無法很好的支持 JSTL1.1 ,要修改為符合 Servlet2.4 規(guī)范的代碼。使 web.xml 成為 Servlet2.4 規(guī)范是十分容易的,需要修改的是其頭部 DTD 聲明。
在 Servlet2.3 之前,校驗和規(guī)范 web.xml 都是使用 DTD ,因此其頭部聲明如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
…
</web-app>
而到了 Servlet2.4 規(guī)范,首此使用了 xmlns 來聲明 web.xml ,因此其頭部聲明為:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
???????? xmlns="http://java.sun.com/xml/ns/j2ee"
???????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????? xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
???????? http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd ">
…
</web-app>
所以,為了支持 Servlet2.4 規(guī)范,應(yīng)該將第三章示例的 web.xml 改成如例 9.6 的樣子。
例 9.6 :修改后的 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
???????? xmlns="http://java.sun.com/xml/ns/j2ee"
???????? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
???????? xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
???????? http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
?<filter>
????? <filter-name>Set Character Encoding</filter-name>
????? <filter-class>struts.sample.cap1.sample3.util.SetCharacterEncodingFilter</filter-class>
????? <init-param>
??????????????? <param-name>encoding</param-name>
??????????????? <param-value>UTF-8</param-value>
????? </init-param>
?</filter>
?<filter-mapping>
????? <filter-name>Set Character Encoding</filter-name>
????? <url-pattern>*.do</url-pattern>
?</filter-mapping>
?<servlet>
??? <servlet-name>action</servlet-name>
??? <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
??? <init-param>
????? <param-name>config</param-name>
????? <param-value>/WEB-INF/struts-config.xml</param-value>
??? </init-param>
??? <init-param>
????? <param-name>debug</param-name>
????? <param-value>2</param-value>
??? </init-param>
??? <load-on-startup>1</load-on-startup>
?</servlet>
?<servlet-mapping>
??? <servlet-name>action</servlet-name>
??? <url-pattern>*.do</url-pattern>
?</servlet-mapping>
?<welcome-file-list>
??? <welcome-file>setSolution.jsp</welcome-file>
?</welcome-file-list>
?<taglib>
??? <taglib-uri>/WEB-INF/struts-template.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-template.tld</taglib-location>
?</taglib>
?<taglib>
??? <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
?</taglib>
?<taglib>
??? <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
?</taglib>
?<taglib>
??? <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
?</taglib>
?<taglib>
??? <taglib-uri>/WEB-INF/struts-template.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-template.tld</taglib-location>
?</taglib>
?<taglib>
??? <taglib-uri>/WEB-INF/struts-tiles.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
?</taglib>
?<taglib>
??? <taglib-uri>/WEB-INF/struts-nested.tld</taglib-uri>
??? <taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
?</taglib>
</web-app>
修改的地方不多,僅僅是頭部的聲明。其他地方完全不必改動,這樣的 web.xml 已經(jīng)支持了 Servlet2.4 規(guī)范了。
9.9.3?JSP 部分: <logic:notEmpty> 和 <c:if> 標(biāo)簽
對于 JSP 顯示頁面的修改是整合的核心部分,在第三章示例的 showAttackSolution.jsp 中出現(xiàn)了這樣的語句:
<logic:notEmpty name="allAttackSolution">
...
</logic:notEmpty>
將類型為 ArrayList 的變量“ allAttackSolution ”從作用范圍中取出,利用 <logic:notEmpty> 標(biāo)簽判斷該 ArrayList 是否為空。
根據(jù)之前討論的“所有判斷標(biāo)簽被 EL 表達(dá)式和 <c:if> 標(biāo)簽替換”,可以利用 <c:if> 標(biāo)簽和 EL 表達(dá)式來修改該段 JSP 代碼。
修改后的結(jié)果如下:
<c:if test="${(requestScope.allAttackSolution != null)
&& fn:length(requestScope.allAttackSolution) != 0}">
...
</c:if>
<logic:notEmpty> 標(biāo)簽其本身具有多種功能:
q???????? 一是判斷是否為 null 。
q???????? 二是當(dāng)它為 String 類型的變量時,判斷字符串長度是否為 0 。
q???????? 三是當(dāng)它為集合類型的變量時,利用集合類的 isEmpty 方法可以判斷是否是一個空的集合。
本示例既然要在替換后與替換前的工作一致,就應(yīng)該對集合做兩個判斷:
q???????? 一是該集合不為 null 。
q???????? 二是該集合中的對象數(shù)量不為 0 。
“ !=null ”的 EL 表達(dá)式實現(xiàn)了集合實例不為 null 的判斷; fn:length() 函數(shù)實現(xiàn)了集合內(nèi)對象數(shù)量不為 0 的判斷,兩個判斷用“ && ”連接起來就實現(xiàn)了 <logic:notEmpty> 標(biāo)簽對于集合判斷的工作。
9.9.4?JSP 部分: <logic:iterate> 和 <c:forEach> 標(biāo)簽
在第三章示例的 showAttackSolution.jsp 中出現(xiàn)了這樣的使用:
<logic:iterate name="allAttackSolution"
id="attackSolution"
type="struts.sample.cap1.sample3.entity.AttackSolution">
???????? <tr>
?????????????????? <td style="word-break: break-all;">
??????????????????????????? <bean:write property="attack_event_code" name="attackSolution" />
?????????????????? </td>
?????????????????? <td style="word-break: break-all;">
??????????????????????????? <bean:write property="attack_mean" name="attackSolution" />
?????????????????? </td>
?????????????????? <td style="word-break: break-all;">
??????????????????????????? <bean:write property="attack_action" name="attackSolution" />
?????????????????? </td>
?????????????????? <td style="word-break: break-all;">
??????????????????????????? <input type="button"
??????????????????? onclick="del('<%=attackSolution.getAttack_event_code()%>');"
value="<bean:message key="message.delete"/>">
?????????????????? </td>
???????? </tr>
</logic:iterate>
由于在 Action 中將顯示的內(nèi)容作為 ArrayList 類型的實例保存在 request 中,因此這段 JSP 頁面標(biāo)簽的工作是:
( 1 )利用 <logic:iterate> 標(biāo)簽對保存在 ArrayList 實例中的所有對象進(jìn)行循環(huán)取得。
( 2 ) ArrayList 類型實例中的對象為 struts.sample.cap1.sample3.entity.AttackSolution 類型, AttackSolution Java 類中的變量屬性都有 get 、 set 方法,因此可以被認(rèn)為是一個標(biāo)準(zhǔn)的 JavaBean 。利用 <bean:write> 標(biāo)簽將 AttackSolution 實例的變量屬性讀取出來,并顯示。
根據(jù)之前討論的“ <logic:iterate> 標(biāo)簽被 <c:forEach> 標(biāo)簽和 EL 表達(dá)式替換”,可以利用 <c:forEach> 標(biāo)簽和 EL 表達(dá)式來修改該段 JSP 代碼。修改的方式有兩種:
q???????? 完全使用 <c:forEach> 標(biāo)簽和 EL 表達(dá)式來替換全部。
q???????? 僅使用 EL 表達(dá)式來替換 <bean:write> 標(biāo)簽。
1. <c:forEach> 標(biāo)簽和 EL 表達(dá)式
<c:forEach> 標(biāo)簽和 EL 表達(dá)式:
<c:forEach items="${requestScope.allAttackSolution}"
var="attackSolution">
???????? <tr>
???????? ???????? <td style="word-break: break-all;" >
??????????????????????????? ${attackSolution.attack_event_code}
?????????????????? </td>
?????????????????? <td style="word-break: break-all;" >
??????????????????????????? ${attackSolution.attack_mean}
?????????????????? </td>
?????????????????? <td style="word-break: break-all;" >
?????????????????? ???????? ${attackSolution.attack_action}
?????????????????? </td>
?????????????????? <td style="word-break: break-all;" >
<input type="button"
onclick="del('${attackSolution.attack_event_code}');"
value="<bean:message key="message.delete"/>">
</td>
???????? </tr>
</c:forEach>
這種修改方式將屏棄 Struts 框架的 <logic:iterate> 標(biāo)簽,而以 <c:forEach> 標(biāo)簽來作為循環(huán)迭代的工作。它的最大優(yōu)點是無需關(guān)注集合中的對象類型,只要保證該對象是一個標(biāo)準(zhǔn)的 JavaBean 就可以了。
2. 使用 EL 表達(dá)式來替換 <bean:write> 標(biāo)簽
<logic:iterate name="allAttackSolution"
id="attackSolution"
type="struts.sample.cap1.sample3.entity.AttackSolution">
???????? <tr>
?????????????????? <td style="word-break: break-all;" >
?????????????????? ??? ${attackSolution.attack_event_code}
?????????????????? </td>
?????????????????? <td style="word-break: break-all;" >
?????????????????? ??? ${attackSolution.attack_mean}
?????????????????? </td>
?????????????????? <td style="word-break: break-all;" >
?????????????????? ??? ${attackSolution.attack_action}
?????????????????? </td>
?????????????????? <td style="word-break: break-all;" >
<input type="button"
onclick="del('${attackSolution.attack_event_code}');"
value="<bean:message key="message.delete"/>">
</td>
???????? </tr>
</logic:iterate>
這種方式對原來的代碼沒有做多大的改動,依然會使用
<logic:iterate>
標(biāo)簽來作為循環(huán)標(biāo)簽。不過對于原來使用
<bean:write>
標(biāo)簽做顯示功能的地方,摒棄了
<bean:write>
標(biāo)簽而直接使用
EL
表達(dá)式。靈活的
EL
表達(dá)式對頁面顯示邏輯有很大幫助,這種方式比較適合熟悉
<logic:iterate>
標(biāo)簽的程序
9.9.5? 完整的 JSP
下面看一個完整的修改后 JSP 頁面的代碼,注釋掉的是被替換之前的代碼,讀者可以比較一下兩種實現(xiàn)方法。請見例 9.7 。
例 9.7 :修改后 showAttackSolution.jsp 。
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<html>
?<head>
??? <!-- 略過 JavaScript 部分 -->
...
?</head>
?<body>
?? <em><bean:message key="message.attacksolutionDB"/></em><p>
?? <table>
??????? <html:errors/>
??? </table>
<bean:message key="message.attackcode"/>:
<input name="attack_event_codeC" value="" type="text">
<bean:message key="message.attackdesc"/>:
<TEXTAREA style="height:100" name=attack_meanC></TEXTAREA>
<bean:message key="message.attacksolution"/>:
<TEXTAREA style="height:100" name=attack_actionC></TEXTAREA>
??? <p/>
??? <html:form action="AddAttackSolutionAction.do">
??????? <html:hidden property="attack_event_code"/>
??????? <html:hidden property="attack_mean"/>
??????? <html:hidden property="attack_action"/>
??????? <input type="button" onclick="add();" value="<bean:message key="message.add"/>">
??????? <input type="button"?
onclick="search();"
value="<bean:message key="message.search"/>">
??? </html:form>
??? <table border=1 cellspacing=1 cellpadding=2>
??????? <tr>
??????????? <td style="background-color: #808080;font-size: 12pt;color: #ffffff;font-weight:
?bold;line-height: 15pt;border: 1px solid #808080;">
??????????????? <bean:message key="message.attackcode"/>
??????????? </td>
??????????? <td style="background-color: #808080;font-size: 12pt;color: #ffffff;font-weight:
?bold;line-height: 15pt;border: 1px solid #808080;">
??????????????? <bean:message key="message.attackdesc"/>
??????????? </td>
??????????? <td style="background-color: #808080;font-size: 12pt;color: #ffffff;font-weight:
?bold;line-height: 15pt;border: 1px solid #808080;">
??????????????? <bean:message key="message.attacksolution"/>
??????????? </td>
??????????? <td style="background-color: #808080;font-size: 12pt;color: #ffffff;font-weight:
?bold;line-height: 15pt;border: 1px solid #808080;">
??????????????? <bean:message key="message.delete"/>
??????????? </td>
??????? </tr>
??????? <!-- 沒有替換前的代碼 -->
??????? <!--
??????????? <logic:notEmpty name="allAttackSolution">
??????????????? <logic:iterate name="allAttackSolution"
id="attackSolution"
type="struts.sample.cap1.sample3.entity.AttackSolution">
??????????????????? <tr>
??????????????????????? <td style="word-break: break-all;" >
??????????????????????????? <bean:write property="attack_event_code"
name="attackSolution"/>
??????????????????????? </td>
??????????????????????? <td style="word-break: break-all;" >
??????????????????????????? <bean:write property="attack_mean" name="attackSolution"/>
??????????????????????? </td>
??????????????????????? <td style="word-break: break-all;" >
??????????????????????????? <bean:write property="attack_action" name="attackSolution"/>
??????????????????????? </td>
??????????????????????? <td style="word-break: break-all;" >
??????????????????????????? <input type="button"
onclick="del('
<bean:write
property="attack_event_code"
name="attackSolution"/>');"
value="<bean:message key="message.delete"/>">
??????????????????????? </td>
??????????????????? </tr>
??????????????? </logic:iterate>
??????????? </logic:notEmpty>
??????? -->
?? ?????
??????? <!-- 僅替換 <bean:write> 標(biāo)簽的代碼 -->
??????? <!--
??????????? <logic:notEmpty name="allAttackSolution">
??????????????? <logic:iterate name="allAttackSolution"
id="attackSolution"
type="struts.sample.cap1.sample3.entity.AttackSolution">
????????? ??????????<tr>
??????????????????????? <td style="word-break: break-all;" >
??????????????????????????? ${attackSolution.attack_event_code}
??????????????????????? </td>
??????????????????????? <td style="word-break: break-all;" >
???????????????????????? ???${attackSolution.attack_mean}
??????????????????????? </td>
??????????????????????? <td style="word-break: break-all;" >
??????????????????????????? ${attackSolution.attack_action}
??????????????????????? </td>
??????????????????????? <td style="word-break: break-all;" >
??????????????????????????? <input type="button"
onclick="del('${attackSolution.attack_event_code}');"
value="<bean:message key="message.delete"/>">
??????????????????????? </td>
??????????????????? </tr>
??????????????? </logic:iterate>
??????????? </logic:notEmpty>
??????? -->
???????
??????? <!-- 替換后的實現(xiàn)代碼 -->??????
??????? <c:if test="${(requestScope.allAttackSolution != null)
&& fn:length(requestScope.allAttackSolution) != 0}">
??????????? <c:forEach items="${requestScope.allAttackSolution}" var="attackSolution">
??????????????? <tr>
??????????????????? <td style="word-break: break-all;" >
??????????????????????? ${attackSolution.attack_event_code}
??????????????????? </td>
??????????????????? <td style="word-break: break-all;" >
??????????????????????? ${attackSolution.attack_mean}
??????????????????? </td>
??????????????????? <td style="word-break: break-all;" >
??????????????????????? ${attackSolution.attack_action}
??????????????????? </td>
??????????????????? <td style="word-break: break-all;" >
??????????????????????? <input type="button"
????????????????????????????? onclick="del('${attackSolution.attack_event_code}');"
value="<bean:message key="message.delete"/>">
??????????????????? </td>
??????????????? </tr>
??????????? </c:forEach>
??????? </c:if>
??? </table>
?</body>
</html>
可以看到,在這個被修改的 JSP 頁面代碼中,利用了 Struts 框架提供的標(biāo)簽來實現(xiàn)提交部分的工作以及國際化資源配置文件讀取顯示的工作,也利用 JSTL 的標(biāo)簽庫和 EL 表達(dá)式來實現(xiàn)頁面邏輯部分的工作。
在 JSP 頁面使用 JSTL 是一種規(guī)范,也是一件令人興奮的事情,因為它使 JSP 部分的程序設(shè)計變得更加有效合理。
posted on 2007-01-18 15:22 nbt 閱讀(3736) 評論(1) 編輯 收藏 所屬分類: Servele&JSP和js