1. 程式人生 > >Display Tag的分頁實現

Display Tag的分頁實現

Display Tag Lib是一個標籤庫,用來處理jsp網頁上的Table,功能非常強,可以對的Table進行分頁、資料匯出、分組、對列排序等等,能夠大大減少程式碼量。
這個是Display Tag的官方網站http://displaytag.sourceforge.net。
首先當然是要下載它的jar包了,這裡可以下載到最新的版本。將jar包放到WEB-INF的lib資料夾下。另外還需要兩個輔助包:apache的commons-lang和standard包,更多的輔助包可以在這裡下載(http://displaytag.sourceforge.net/10/dependencies.html

)。

   在web.xml下新增一個filter
   <filter>
       <filter-name>exportFilter</filter-name>
       <filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class>
   </filter>

   在jsp頁面做一個引用:

<%@ taglib uri=“http://displaytag.sf.net/el” prefix=“display” %>

   首先我們定義一個list

<%
List test = new ArrayList( 6 );
test.add( “Test String 1” );
test.add( “Test String 2” );
test.add( “Test String 3” );
test.add( “Test String 4” );
test.add( “Test String 5” );
test.add( “Test String 6” );
request.setAttribute( “test”, test );
%>

   當我們想在jsp頁面上顯示這個list時,我們只需要寫一句話
   <display:table name="test" />
   display tag會自動生成一個table

   如果list是從控制層丟擲來的,name可使用EL表示式表示
   <display:table name="${test}" />

   這是最簡單的display tag的使用,我們可以給它加上樣式等,也可以定義顯示的列,下面的table顯示覆雜一些

<display:table name=“test” styleClass=“list” cellspacing=“0” cellpadding=“0”>
<display:column property=“id” title=“ID” class=“idcol”/>
<display:column property=“name” />
<display:column property=“email” />
<display:column property=“description” title=“Comments”/>
</display:table>

   如果想要給它加個連結也很簡單,下面的程式碼給name加了連線,並附帶id引數,email也自動連線到mailto:XXX

<display:table name=“test” styleClass=“list” cellspacing=“0” cellpadding=“0”>
<display:column property=“id” title=“ID” class=“idcol”/>
<display:column property=“name” url=“detail.jsp” paramId=“id” paramProperty=“id”/>
<display:column property=“email” autolink=“true”/>
<display:column property=“description” title=“Comments”/>
</display:table>

下面介紹幾個Display最常用的功能,更多功能請參考http://displaytag.homeip.net/displaytag-examples-1.1/。

  1. 分頁
    如果想對程式碼分頁,只需在display:table標籤中新增一項pagesize=“每頁顯示行數”,如
    <display:table name=“test” pagesize=“10”/>

  2. 對列排序
    display tag可對列進行排序,就是點選列名,對該列的資料進行排序。你只需對想要排序的列新增 sort=“true” 就OK,如下面的程式碼可對前三列進行排序。在display:table中新增defaultsort=“列數”,可預設對指定的列排序。
    <display:table name=“test” styleClass=“list” cellspacing=“0” cellpadding=“0” defaultsort=“1”>
    <display:column property=“id” title=“ID” class=“idcol” sort=“true”/>
    <display:column property=“name” url=“detail.jsp” paramId=“id” paramProperty=“id” sort=“true”/>
    <display:column property=“email” autolink=“true” sort=“true”/>
    <display:column property=“description” title=“Comments”/>
    </display:table>
    如果table有分頁,Display Tag預設只對當前頁進行排序,如果想對整個list排序,可以在display:table之間新增一段程式碼:
    <display:setProperty name=“sort.amount” value=“list”/>

  3. 匯出資料
    在display:table中新增export=“true”,看看會出現什麼!Display Tag預設會提供三種資料匯出方式:CSV、Excel、XML 。
    另外Display Tag還可以匯出為PDF格式,在http://prdownloads.sourceforge.net/itext/下載一個輔助包iText.jar,copy到lib目錄下,然後在display:table之間新增一段程式碼:
    <display:setProperty name=“export.pdf” value=“true”/>,大功告成。

  4. Display Tag的屬性設定
    前面所說的display:setProperty 是一種改變Display Tag屬性的方法,但是在每個jsp中都要寫太麻煩了。
    Display Tag中設定了很多預設的屬性,它有一個專門的屬性檔案,是在它的jar包中的displaytag/properties/TableTag.properties
    想要改變它的預設屬性,我們可以在WEB-INF\classes下新建一個檔案displaytag.properties,仿照TableTag.properties中屬性的格式設定需要修改的屬性。
    TableTag.properties中的# messages中設定的是顯示在頁面上的提示資訊。預設是英文的,我們可以把它改為中文的。不過這裡只能使用unicode,就是說中文字元必須轉換為 unicode碼,這個可以使用jdk自帶的native2ascii.exe進行轉換。

  5. 其它功能
    DisplayTag還有一些很實用的小功能,這裡提兩個。一個是對資料的Format,這是1.1版本新增的新功能,可以使用標籤的方式格式化時間、數字、字串。比如日期,在需要格式化的column標籤中新增format="{0,date,yyyy-MM-dd}",第一個引數為格式化的資料序號,第二個引數是資料型別,數字為number,第三個引數為資料格式。
    另外一個功能是對table資料的合計功能。在table標籤中新增 decorator=“org.displaytag.decorator.TotalTableDecorator”,然後在想要進行合計的資料列的 column標籤中新增 total=“true”,該列就可以被計算總數了。但這個功能有個缺點,不能用在有分頁的時候,它只能合計第一頁的資料。

DisplayTag的不足
初次使用DisplayTag的人可能會覺得驚喜,但是用久了會發現很多問題,最大的問題是對中文的支援不好,比如如果查詢條件中有中文,就無法翻頁,無法對中文排序,將中文匯出為指定檔案時出現亂碼等等。這些問題有時候會讓人很鬱悶,有時候逼得你要去修改它的原始碼。下面是對以上幾個問題的解決方法:
1. 對於中文無法翻頁、排序,最簡單的辦法是修改Tomcat下的server.xml檔案。找到HTTP的Connector標籤,在裡面新增一項 URIEncoding="…",引號裡面的內容取決於你的頁面編碼,比如可以是GBK,UTF8等。這樣上面兩個問題就可以解決了。
2. 匯出為檔案:其實這個功能除了中文支援外還有很多其它問題,比如它會將Html標籤一起匯出、只匯出顯示的內容,但如果對table進行了 decorator,decorator後的內容無法匯出。如果想要將中文正確匯出,需要修改DisplayTag原始碼。
下載相同版本的原始碼,在org.displaytag.export.ExcelView.java檔案中找到getMimeType()方法,將此方法修改為 return “application/vnd.ms-excel;charset=GB2312”;,修改後匯出資料的速度會慢很多,不過將就吧。
3. 新版的DisplayTag1.1添加了對一次取部分資料的支援,相關的標籤包括partialList和size,需要設定partialList="true"和size的大小。具體怎麼用偶還沒研究。

DisplayTag是一個非常好用的表格顯示標籤,適合MVC模式,其主頁在http://displaytag.sourceforge.net

一、最簡單的情況,未使用display:column/標籤

<%request.setAttribute( “test”, new ReportList(6) );%>
<display:table name=“test” />

標籤遍歷List裡的每一個物件,並將物件裡的所有屬性顯示出來。一般用於開發的時候檢查物件資料的完整性。

二、使用display:column/標籤的情況

<display:table name=“test”>
<display:column property=“id” title=“ID” />
<display:column property=“name” />
<display:column property=“email” />
<display:column property=“status” />
<display:column property=“description” title=“Comments”/>
</display:table>

property對應List裡物件的屬性(用getXXX()方法取得),title則對應表格表頭裡的列名。定義列有兩種方式:

A、<display:column property=“email” />

使用display:column/標籤裡的property屬性來定義

B、<display:column title=“email”>[email protected]</display:column>

display:column/標籤體裡增加內容,可以是常量,也可以用其他標籤等等

兩種方式比較,用property屬性來定義更加快速和利於排序。

三、表格顯示樣式的定義

A、在display:table/display:column/標籤裡指定標準的html屬性,煩瑣

B、修改樣式表
<display:table name=“test” class=“mars”>
<display:column property=“id” title=“ID” class=“idcol”/>
<display:column property=“name” />
<display:column property=“email” />
<display:column property=“status” class=“tableCellError” />
<display:column property=“description” title=“Comments”/>
</display:table>

通過class屬性來指定所要應用的樣式。可以在其預設樣式表裡(./css/screen.css)直接修改

四、標籤取得資料的資料來源

有四種範圍

pageScope
requestScope (預設) <display:table name=“test2” >
sessionScope <display:table name=“sessionScope.holder.list” > 注意,這裡要指定範圍,非預設
applicationScope

五、通過增加id屬性建立隱含的物件

<display:table name=“test” id=“testit”>
<display:column property=“id” title=“ID” />
<display:column property=“name” />
<display:column title=“static value”>static</display:column>
<display:column title=“row number (testit_rowNum)”>
<%=pageContext.getAttribute(“testit_rowNum”)%></display:column>
<display:column title="((ListObject)testit).getMoney()">
<%=((ListObject)pageContext.getAttribute(“testit”)).getMoney()%>
</display:column>
</display:table>

注意到在display:table/裡增加了id屬性,這時就在page context裡建立了一個隱含物件,指向List裡的當前物件,

可以通過(ListObject)pageContext.getAttribute(“id”)來捕獲這個物件。同時還建立了一個id_rowNum物件,同樣,可

通過pageContext.getAttribute(“testit_rowNum”)來捕獲,它僅僅代表當前行的行數。

有了這兩個隱含物件,就可以通過其他標籤來訪問,例如Jstl:

<display:table id=“row” name=“mylist”>
<display:column title=“row number” >
<c:out value=" r o w r o w N u m &quot; / &gt; &lt; / d i s p l a y : c o l u m n &gt; &lt; d i s p l a y : c o l u m n t i t l e = &quot; n a m e &quot; &gt; &lt; c : o u t v a l u e = &quot; {row_rowNum}&quot;/&gt; &lt;/display:column&gt; &lt;display:column title=&quot;name&quot; &gt; &lt;c:out value=&quot; {row.first_name}"/>
<c:out value="${row.last_name}"/>
</display:column>
</display:table>

六、顯示部分資料

顯示開始五條資料:通過設定length屬性

<display:table name=“test” length=“5”>
<display:column property=“id” title=“ID” />
<display:column property=“email” />
<display:column property=“status” />
</display:table>

顯示第三到第八條資料:通過設定offset和length屬性

<display:table name=“test” offset=“3” length=“5”>
<display:column property=“id” title=“ID” />
<display:column property=“email” />
<display:column property=“status” />
</display:table>

七、對email和url地址的直接連線

<display:table name=“test” >
<display:column property=“id” title=“ID” />
<display:column property=“email” autolink=“true” />
<display:column property=“url” autolink=“true” />
</display:table>

如果要顯示的物件裡包含email和url地址,則可以在display:column裡直接設定autolink="true"來直接連線

八、使用裝飾模式轉換資料顯示(寫自己的 decorator )

A、對整個表格應用decorator

<display:table name=“test” decorator=“org.displaytag.sample.Wrapper” >
<display:column property=“id” title=“ID” />
<display:column property=“email” />
<display:column property=“status” />
<display:column property=“date” />
<display:column property=“money” />
</display:table>
org.displaytag.sample.Wrapper即自己寫的decorator,它要繼承TableDecorator類,看看它的一個方法:
public String getMoney()
{
return this.moneyFormat.format(((ListObject) this.getCurrentRowObject()).getMoney());
}

很明顯,它通過父類的getCurrentRowObject()方法獲得當前物件,然後對其getMoney()方法進行‘油漆’

B、對單獨的column應用decorator

<display:table name=“test”>
<display:column property=“id” title=“ID” />
<display:column property=“email” />
<display:column property=“status” />
<display:column property=“date” decorator=“org.displaytag.sample.LongDateWrapper” />
</display:table>
org.displaytag.sample.LongDateWrapper要實現ColumnDecorator介面,它的方法:
public final String decorate(Object columnValue)
{
Date date = (Date) columnValue;
return this.dateFormat.format(date);
}

顯然,它獲得不了當前物件(因為它實現的是介面),僅僅是獲得該物件的columnValue,然後‘油漆’

九、建立動態連線

有兩種方法建立動態連線:

A、在display:column/裡通過增加href、paramId、paramName、paramScope、paramProperty屬性

href       基本的URL 地址
paramId     加在URL 地址後的引數名稱
paramName    資料bean的名稱,一般為null(即使用當前List裡的物件)
paramScope    資料bean的範圍,一般為null
paramProperty  資料bean的屬性名稱,用來填充URL 地址後的引數值
<display:table name=“sessionScope.details”>
<display:column property=“id” title=“ID” href=“details.jsp” paramId=“id” />
<display:column property=“email” href=“details.jsp” paramId=“action” paramName=“testparam” paramScope=“request” />
<display:column property=“status” href=“details.jsp” paramId=“id” paramProperty=“id” />
</display:table>

這種方法簡便直接,但缺點是無法產生類似details.jsp?id=xx&action=xx的複合URL

B、應用decorator 建立動態連線:

<display:table name=“sessionScope.details” decorator=“org.displaytag.sample.Wrapper” >
<display:column property=“link1” title=“ID” />
<display:column property=“email” />
<display:column property=“link2” title=“Actions” />
</display:table>
org.displaytag.sample.Wrapper裡的方法:
public String getLink1()
{
ListObject lObject= (ListObject)getCurrentRowObject();
int lIndex= getListIndex();
return “<a href=“details.jsp?index=” + lIndex + “”>” + lObject.getId() + “”;
}

public String getLink2()
{
ListObject lObject= (ListObject)getCurrentRowObject();
int lId= lObject.getId();

return "<a href=“details.jsp?id=” + lId

  • “&action=view”>View | "
  • "<a href=“details.jsp?id=” + lId
  • “&action=edit”>Edit | "
  • "<a href=“details.jsp?id=” + lId
  • “&action=delete”>Delete";
    }

十、分頁

實現分頁非常的簡單,增加一個pagesize屬性指定一次想顯示的行數即可

<display:table name=“sessionScope.test” pagesize=“10”>
<display:column property=“id” title=“ID” />
<display:column property=“name” />
<display:column property=“email” />
<display:column property=“status” />
</display:table>

十一、排序

排序實現也是很簡單,在需要排序的column裡增加sortable="true"屬性,headerClass="sortable"僅僅是

指定顯示的樣式。column裡的屬性物件要實現Comparable介面,如果沒有的話可以應用decorator

defaultsort=“1”       預設第一個column排序
defaultorder=“descending”  預設遞減排序
<display:table name=“sessionScope.stest” defaultsort=“1” defaultorder=“descending”>
<display:column property=“id” title=“ID” sortable=“true” headerClass=“sortable” />
<display:column property=“name” sortable=“true” headerClass=“sortable”/>
<display:column property=“email” />
<display:column property=“status” sortable=“true” headerClass=“sortable”/>
</display:table>

注意的是,當同時存在分頁時排序僅僅針對的是當前頁面,而不是整個List都進行排序

十二、column 分組

分組只是需要在column裡增加group屬性

<display:table name=“test” class=“simple”>
<display:column property=“city” title=“CITY” group=“1”/>
<display:column property=“project” title=“PROJECT” group=“2”/>
<display:column property=“amount” title=“HOURS”/>
<display:column property=“task” title=“TASK”/>
</display:table>

十三、匯出資料到其他格式(頁面溢位filter??)

display:table/裡設定export=“true”

display:column/裡設定media=“csv excel xml pdf” 決定該欄位在匯出到其他格式時被包不包含,不設定則都包含

<display:setProperty name=“export.csv” value=“false” />

決定該種格式能不能在頁面中匯出

<display:table name=“test” export=“true” id=“currentRowObject”>
<display:column property=“id” title=“ID”/>
<display:column property=“email” />
<display:column property=“status” />
<display:column property=“longDescription” media=“csv excel xml pdf” title=“Not On HTML”/>
<display:column media=“csv excel” title=“URL” property=“url”/>
<display:setProperty name=“export.pdf” value=“true” />
<display:setProperty name=“export.csv” value=“false” />
</display:table>

十四、配置屬性,覆蓋預設

兩種方法:

A、在程式classpath下新建displaytag.properties檔案

B、對於單個表格,應用display:setProperty標籤

具體可配置的屬性:http://displaytag.sourceforge.net/configuration.html

十五、一個完整的例子

<display:table name=“test” export=“true” sort=“list” pagesize=“8”>
<display:column property=“city” title=“CITY” group=“1” sortable=“true” headerClass=“sortable”/>
<display:column property=“project” title=“PROJECT” group=“2” sortable=“true” headerClass=“sortable”/>
<display:column property=“amount” title=“HOURS”/>
<display:column property=“task” title=“TASK”/>
</display:table>

sort=“list” 對整個list進行排序

匯出資料到其他格式時,group無效