JSP部分:<logic:iterate>和<c:forEach>标签
在第三章示例的showAttackSolution.jsp中出现了这样的使用:
<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"
οnclick="del(‘<%=attackSolution.getAttack_event_code()%>‘);"
value="<bean:message key="message.delete"/>">
</td>
</tr>
</logic:iterate>
由于在Action中将显示的内容作为ArrayList类型的实例保存在request中,因此这段JSP页面标签的工作是:
(1)利用<logic:iterate>标签对保存在ArrayList实例中的所有对象进行循环取得。
(2)ArrayList类型<nobr><a target="_blank" style="color:rgb(0,0,255)">实例</a></nobr>中的对象为struts.sample.cap1.sample3.entity.AttackSolution类型,AttackSolution Java类中的变量属性都有get、set方法,因此可以被认为是一个标准的JavaBean。利用<bean:write>标签将AttackSolution实例的变量属性读取出来,并显示。
根据之前讨论的“<logic:iterate>标签被<c:forEach>标签和EL表达式替换”,可以利用<c:forEach>标签和EL表达式来修改该段JSP代码。修改的方式有两种:
q完全使用<c:forEach>标签和EL表达式来替换全部。
q仅使用EL表达式来替换<bean:write>标签。
1. <c:forEach>标签和EL表达式
<c:forEach>标签和EL表达式:
<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"
οnclick="del(‘${attackSolution.attack_event_code}‘);"
value="<bean:message key="message.delete"/>">
</td>
</tr>
</c:forEach>
这种修改方式将屏弃Struts框架的<logic:iterate>标签,而以<c:forEach>标签来作为循环迭代的工作。它的最大优点是无需关注集合中的对象类型,只要保证该对象是一个标准的JavaBean就可以了。
2.使用EL表达式来替换<bean:write>标签
<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"
οnclick="del(‘${attackSolution.attack_event_code}‘);"
value="<bean:message key="message.delete"/>">
</td>
</tr>
</logic:iterate>
这种方式对原来的代码没有做多大的改动,依然会使用<logic:iterate>标签来作为循环标签。不过对于原来使用<bean:write>标签做显示功能的地方,摒弃了<bean:write>标签而直接使用EL表达式。灵活的EL表达式对页面显示逻辑有很大帮助,这种方式比较适合熟悉<logic:iterate>标签的程序设计者。
9.9.5完整的JSP
下面看一个完整的修改后JSP页面的代码,注释掉的是被替换之前的代码,读者可以比较一下两种实现方法。请见例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" οnclick="add();" value="<bean:message key="message.add"/>">
<input type="button"
οnclick="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"
οnclick="del(‘
<bean:write
property="attack_event_code"
name="attackSolution"/>‘);"
value="<bean:message key="message.delete"/>">
</td>
</tr>
</logic:iterate>
</logic:notEmpty>
-->
<!--仅替换<bean:write>标签的代码-->
<!--
<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"
οnclick="del(‘${attackSolution.attack_event_code}‘);"
value="<bean:message key="message.delete"/>">
</td>
</tr>
</logic:iterate>
</logic:notEmpty>
-->
<!--替换后的实现代码-->
<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"
οnclick="del(‘${attackSolution.attack_event_code}‘);"
value="<bean:message key="message.delete"/>">
</td>
</tr>
</c:forEach>
</c:if>
</table>
</body>
</html>
可以看到,在这个被修改的JSP页面代码中,利用了Struts框架提供的标签来实现提交部分的工作以及国际化资源配置文件读取显示的工作,也利用JSTL的标签库和EL表达式来实现页面逻辑部分的工作。
在JSP页面使用JSTL是一种规范,也是一件令人兴奋的事情,因为它使JSP部分的程序设计变得更加有效合理。
9.10本章回顾
在本章的介绍中,笔者花了很大一段来介绍JSTL的EL<nobr><a target="_blank" style="color:rgb(0,0,255)">表达式</a></nobr>和标签库的工作,接着也对Struts标签库和JSTL标签库中相类似的标签作了比较,最后还修改了第三章的示例来真正的将Struts框架和JSTL结合在了一起。
不得不说的是,JSTL实在是很棒的技术,它为JSP的程序设计者带来了福音。
当在JSP<nobr><a target="_blank" style="color:rgb(0,0,255)">页面</a></nobr>使用Java语言片段已经成为了历史,在JSP页面自定义<nobr><a target="_blank" style="color:rgb(0,0,255)">标签</a></nobr>库已经不成为时尚的今天,何不试试JSTL呢?