一,問題概述
jstl的出現,的確標準化了我們的jsp開發,也使得頁面變得更加清晰,這也正是j2ee推出jstl的一個意圖。例如jsp中要求取出request中保存的一個屬性username,以前習慣的方式:
<%
string username=(string)request.getattribute("username");
out.println(username);
%>
或者
<%
string username=(string)request.getattribute("username");
%>
<%=username%>
在使用jstl后,則可以直接書寫為:
<c:out value="${username}"/>
或者直接
${username}
可見去掉<%%>的使用后,jsp的確簡潔了許多。
不過在具體使用中,我們發現jstl提供的標簽庫只能在一定程度上滿足我們的應用邏輯要求,有些時候不得不在jsp中借助java代碼來實現。例如在jsp中要求取出request屬性信息中的用戶列表userlist,列出每個用戶時,如果該用戶為管理員用戶(假設該判斷由一個工具類的靜態方法來提供),則該用戶顯示為紅色,以前習慣的方式為:
<%
list users=(list)request.getattribute("userlist");
iterator us=users.iterator();
while(us.hasnext()){
user user=(user)us.next();
booean hasadminrole=permissionutil.hasrole(user,role.admin);
string color="black";
if(hasadminrole){
color="red";
}
%>
<font color="<%=color%>"><%=user.getname%></font>
<%
}
%>
那上面的邏輯是否可以使用jstl來實現呢,我們嘗試一下:
<c:set var="color" value="black"/>
<c:foreach items="${userlist}" var="user">
<c:if test="如果是管理員">
<c:set var="color" value="red"/>
</c:if>
<font color="<c:out value='${color}'/>"><c:out value="${user.name}"/></font>
</c:foreach>
基本上可以,但是問題就在于如何判斷每次循環到的用戶是否為管理員呢?我們知道判斷方法是在一個工具類中實現的,而jstl標簽中還沒有可以直接調用類的方法的標簽,因此僅是標簽的jstl無法滿足這個要求。
二,解決方式
1,寫一個自定義標簽,來判斷當前循環到的用戶是否為管理員,如下:
<%@ taglib uri="/web-inf/myrolecheck.tld" prefix="role"%>
<c:set var="color" value="black"/>
<c:foreach items="${userlist}" var="user">
<role:check user="${user.name}" role="admin">
<c:set var="color" value="red"/>
</role:check>
<font color="<c:out value='${color}'/>"><c:out value="${user.name}"/></font>
</c:foreach>
當然,上面的方式要求我們自定義的標簽能夠支持對el方式的解析,這實際上可以通過evalhelper類來實現。
2,聯合使用jstl與java api。使用這種方式,我們需要對jstl了解的更深一些,我們知道jstl和java api(或者說是<%%>方式)是很不相同的兩種書寫方式,他們之間的變量有些可以很好的傳遞,但有些卻讓人摸不著頭腦,例如:
1)<%%>變量在jstl中獲取的例子:
<%
string username="zhangsan";
pagecontext.setattribute("username",username);
%>
<c:out value="${username}"/>
即:jsp頁面中<%%>中的變量在定義后,需要放置到pagecontext屬性中,才能被獲?。ó斎灰部梢苑胖玫絩equest和session、applicatio中,這要根據實際應用來做決定,一般只是在頁面中使用的化,使用pagecontext就可以了)。
2)jstl變量在<%%>中獲取的例子:
<c:set var="username" value="zhangsan"/>
<%
string username=(string)pagecontext.getattribute("username");
%>
上面為什么要在pagecontext中來獲取呢,因為c:set方式定義的變量默認是存放在pagecontext的屬性中的,當然了如果在定義是指定了作用范圍,則也需要通過相應作用范圍的頁面對象來獲取該屬性,例如:
<c:set var="username" value="zhangsan" scope="session"/>
<%
string username=(string)session.getattribute("username");
%>
另外,還要主要一點,jstl中的許多操作都用到了var屬性,例如c:foreach、c:import等等,這些var所代表的變量默認也是存放在pagecontext中的,當然有些標簽還提供了scope屬性,這也意味著其var所代表的變量會存放到scope指定的范圍之中。
在理解這些的基礎上,再來使用聯合方式解決最初的問題就相對好說多了,如下:
<c:foreach items="${userlist}" var="user">
<%
user user=(user)pagecontext.getattribute("user");
booean hasadminrole=permissionutil.hasrole(user,role.admin);
string color="black";
if(hasadminrole){
color="red";
}
%>
<font color="<%=color%>"><c:out value="${user.name}"/></font>
</c:foreach>
新聞熱點
疑難解答