Display Tag Lib是一個標籤庫,用來處理jsp網頁上的Table,功能很是強,能夠對的Table進行分頁、數據導出、分組、對列排序等等,反正我在作項目時須要的功能它都給我提供了,並且使用起來很是的方便。可以大大減小代碼量。 介個是Display Tag的官方網站http://displaytag.sourceforge.net。 首先固然是要下載它的jar包了,這裏能夠下載到最新的版本。將jar包放到WEB-INF的lib文件夾下。另外還須要兩個輔助包:apache的commons-lang和standard包,更多的輔助包能夠在這裏下載。css
在web.xml下添加一個filter html
<filter> java
<filter-name>exportFilter</filter-name> mysql
<filter-class>org.displaytag.filter.ResponseOverrideFilter</filter-class> web
</filter>sql
在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 /> display tag會自動生成一個tableapache
若是list是從控制層拋出來的,name可以使用EL表達式表示 <display:table />session
這是最簡單的display tag的使用,咱們能夠給它加上樣式等,也能夠定義顯示的列,下面的table顯示覆雜一些app
<display:table styleClass="list" cellspacing="0" cellpadding="0">
<display:column property="id" title="ID" />
<display:column property="name" />
<display:column property="email" />
<display:column property="description" title="Comments"/>
</display:table>
若是想要給它加個連接也很簡單,下面的代碼給name加了鏈接,並附帶id參數,email也自動鏈接到mailto:XXX
<display:table styleClass="list" cellspacing="0" cellpadding="0">
<display:column property="id" title="ID" />
<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://www.displaytag.org/index.jsp。 1. 分頁 若是想對代碼分頁,只需在display:table標籤中添加一項pagesize="每頁顯示行數",如 <display:table pagesize="10"/>
2. 對列排序 display tag可對列進行排序,就是點擊列名,對該列的數據進行排序。你只需對想要排序的列添加 sort="true" 就OK,以下面的代碼可對前三列進行排序。在display:table中添加defaultsort="列數",可默認對指定的列排序。
<display:table styleClass="list" cellspacing="0" cellpadding="0" defaultsort="1">
<display:column property="id" title="ID" 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 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 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進行轉換。
6. displaytag的翻頁機制 這多是displaytag的侷限性了,它的翻頁機制是這樣的: 若是一個list中有10000個bean,按照它的機制,若是是第一頁(每頁n條),它會把前n條數據取出來,而後再把剩餘的10000-n條刪除,當你點擊頁面「2」的時候,它再從後臺繞一圈,把第二頁的數據,也就是把第n+1-2n條記錄取出來,把剩餘的刪除。這樣,它實現了翻頁,又防止了內存佔用過大。 可是,無論怎麼說,它仍是有一個取出全部條數的動做的,在極大數據量的狀況下,有可能形成內存溢出。
8. displaytag中decorator一例
import org.displaytag.decorator.TableDecorator;
import Java.util.HashMap;
import java.text.SimpleDateFormat; import java.util.Date;
public class BulletinListDecorator extends TableDecorator{
private String bulletinId = null;
private String title = null;
private SimpleDateFormat sdf = null;
private int i = 0;
public BulletinListDecorator() {
sdf = new SimpleDateFormat("yy-MM-dd"); }
public String getBulletinId(){
i+=1;
return ""+i;
}
public String getTitle(){
bulletinId = (String)((HashMap) this.getCurrentRowObject()).get("bulletinId");
title = (String)((HashMap) this.getCurrentRowObject()).get("title");
return ""+title+""; }
public String getLastPubD(){
return sdf.format((Date)((HashMap) this.getCurrentRowObject()).get("lastPubD"));
}
}
<display:table decorator="com.ztesoft.ds.application.web.bulletin.decorator.BulletinListDecorator"> <display:column property="bulletinId" titleKey="titlePage.seq" align="center" headerClass="ValueTd"/> <display:column property="title" titleKey="titlePage.title" align="center" headerClass="ValueTd"/> <display:column property="lastPubD" titleKey="titlePage.time" align="center" headerClass="ValueTd"/> <display:column property="className" titleKey="titlePage.class" align="center" headerClass="ValueTd"/> <display:column property="clickNo" titleKey="titlePage.clickNo" align="center" headerClass="ValueTd"/> </display:table>
其中bulletinList是一個ArrayList,titleKey指向了properties文件
補充:
一:
在display:table中添加自定義的列用 display:column ,將其屬性media的值設置爲html便可,以下例子:
<display:table name="list" pagesize="5" >
<display:column title="刪除" media="html">
<input type="button" value="刪除" />
</display:column>
</display:table>
二:
在寫對應於bean裏面的列時,display:column 中property對應的值是bean裏面的屬性的名字,大小寫必須一致,例如:有個actionform類,有屬性 private String _Name; 則property的值也必須爲"_Name",不然提示找不到列。
*****************************************************************
轉:
displaytag 學習筆記總結(1)
6,列表的子集 <display:table name="mylist" offset="m" length="n"/> offset 爲第一個數據在mylist中的序號。 length 爲顯示的記錄條數。
7,自動設置連接 可以把此列的內容做爲連接,鏈接的url和內容一致。 固然必須格式有效的url,不然寫了也沒有鏈接。
( 自認爲這個功能通常。 由於鏈接的內容和顯示的內容一般不同。 ) 固然能夠在<display:column href="">在這裏給某列指定全部的連接爲同一個鏈接。 或者<display:column ><a href="">sdfs</a></display:column >二者效果是同樣的。
!!!那麼,若是鏈接的url不是列內容,並且每行的連接都不相同,這個時候怎麼辦? 就好像廣告列表有商戶名稱,商戶名稱是一個鏈接,鏈接到商戶的具體信息頁面。 鏈接的url確定不一樣。如何處理? 如今還不知道,接着往下看。
8,使用裝飾類來轉換數據。
<display:table name="test" decorator="org.displaytag.sample.Wrapper" > 用來轉換數據內容的。通常用來格式化信息。 此類必繼承TableDecorator。 順便介紹一個格式化時間的包 org.apache.commons.lang.time.FastDateFormat; 格式化金錢的包 java.text.DecimalFormat; 思路就是覆蓋List中具體類型的getXXX方法。 this.getCurrentRowObject() 獲得當前行的數據。 this.getListIndex() 獲得當前行的序號。 以後就轉化爲List中存放的具體類型,以後獲得某列的數據。 返回格式化後的數據。
!!!!另外我看到,裝飾類增長了一些getXXX方法,這些方法並無在ListObject中定義。 還不知道這樣作有什麼好處? <display:column property="date" decorator="org.displaytag.sample.LongDateWrapper" /> 這樣僅僅對一列數據進行格式化,須要繼承ColumnDecorator 須要實現:String decorate(Object columnValue)方法。此方法一樣接受一個Object參數, 此參數就是對象的某個具體屬性值,直接轉化爲對應類型,而後格式化,返回String。
9,創建動態連接。 兩種方式能夠創建動態連接。 第一種方式直接在頁面上使用 <display:column href="baseurl" paramId="paramid" /> http://baseurl/paramid=columnvalue <display:column href="baseurl" paramId="paramid" paramName=「name」 paramScope="scope"/> http://baseurl/paramid=scope範圍內的名字爲name的值 <display:column href="baseurl" paramId="paramid" paramProperty=「propertyname」/> http://baseurl/paramid=名字爲propertyname的屬性值
這種方式處理簡單的連接十分有效,可是連接參數值若是經過查詢數據庫等比較複雜的方式獲得的話,這種方式 就不適應了。這時候就必須使用第二種方法。
第二種方法,在裝飾類中得到鏈接。 裝飾類多定義一些getXXX方法,那麼頁面上就可使用<display:column propety="XXX" ..>來使用裝飾類de getXXX方法。好,這樣一來,在裝飾類的getXXX方法裏,獲得此行對象,這樣對象的各個屬性就都能獲得, 以後去查數據庫也好,去完成負責的判斷邏輯也好,都很容易實現,別忘了,而後拼裝起來,並寫成一個 <a href="....">這樣的字符串返回。 好,頁面直接一句話就可獲得此拼裝的《a》了。<display:column propety="XXX" ..>
第二種方法比較好些,由於能夠顯得更靈活。想怎麼寫就怎麼寫。第一種方法就是簡單地實現。 10,翻頁。 1,怎麼獲得每行的序號? <display:table id="xxx" ...> 使用<%=pageContext.getAttribute("xxx_rowNum")%>確定好用。 可是<c:out value="${row_rowNum}"/>這種方式就很差用。也不知道差哪了。
翻頁很簡單。就是在<display:table pagesize="m">這樣來指定每頁的數量就能夠了。 自動出現換頁的索引,上下頁等等東西。 實在是方便。可是問題就是一次傳下來不少東西,性能很差。等一會看看如何改良。
11,自動設置排序 <display:table name="sessionScope.stest" defaultsort="1" defaultorder="descending"> <display:column property="id" title="ID" sortable="true" headerClass="sortable" /> 能夠設定默認時按照哪列排序,是升序仍是降序。本例設置第一列默認時降序。 每列都得對象都必須實現了Comparable接口才能被設置成sortable="true". 若是沒有實現Comparable,那麼必須寫一個裝飾類。 另外須要注意, 他只對當前頁面進行排序。而不是所有。在翻頁時特別須要注意。 要想實現所有的排序,那麼必須從新寫Action往網頁傳新的List了。
12,如何分組 按照某列進行分組顯示。 這個功能真不錯。 <display:column property="city" title="CITY" group="1"/> <display:column property="project" title="PROJECT" group="2"/> 這樣不只僅結果能夠分組,並且還能夠省略掉重複的數據,例如city列,project列都有 A ,B ,A,B 兩行那麼第二行這兩列就不顯示了。
一樣只能對當前頁進行分組。
注意:第一列必定要1,第二列必定是2,不然出NUllPoint 錯誤。
13,統計 好東西啊。能夠對分組進行統計,也能夠對全部行進行統計。 主要靠TableDecorator類finishRow()返回統計結果,放到頁面去顯示。
TableDecorator類方法getDecoratedObject()獲得整個結果集。通常把它轉化成List,由於大多數狀況下結果 是存放在List中的。 public final String finishRow() {}當一行結束時執行此方法。因此用它來判斷是否須要計算城市統計, 抑或是所有統計。 至關於事件處理。返回的字符串也將在頁面上顯示。本例返回了<tr><td>...</td><tr>這樣的三份。 這樣就在表中嵌套進了三行。用來顯示統計是足夠了。
14,導出數據 很簡單。talbe裏設置export=「true」就好了。配置文件也要設置好export.xml = true , 這樣才能導出xml。 類推pdf、excel、html、csv。 每一個列能配置是否在某種格式中顯示,語法<display:column media="csv excel" 。。 不配置就在全部格式中都顯示。
另外須要注意: 被包含的文件不能使用這個功能,非要使用,就的用過濾器。之後再深研究吧。
15,配置DisplayTag. 在應用的classpath路徑上拷貝一個TableTag.properties,並命名爲displaytag.properties. 這樣就默認取displaytag.properties裏的配置了。想漢化,很簡單。就須要把displaytag_zh.properties放到 classpath路徑下就能夠了。
標題像漢化:由於默認是jstl的資源文件使用方式。因此得先學習jstl的 我知道了jstl.fmt如何使用資源文件。好了,jstl 首先必須用fmt:bunlle指定一個資源文件,而後才能 在他的body部分使用此資源文件,頗麻煩。
而displaytag呢? 沒有這麼麻煩,若是與struts搭配使用,適用struts的資源文件固然最合理了。 你必須在displaytag.properties裏定義好一個 參數,#locale.provider=org.displaytag.localization.I18nJstlAdapter locale.provider=org.displaytag.localization.I18nStrutsAdapter 就這麼簡單,就可以使用struts配置文件了。我今天居然看了一下午。哎,苦於沒有好點的資料啊。
問題是:若是不合struts搭配使用。若是僅僅在jstl環境下,displaytag又該如何使用jstl的資源文件呢? 你必須象在jstl環境裏同樣使用<fmt:bundl>指定好資源文件,以後把displaytag標籤放到他的body 後,就可使用jstl的資源文件了!!!!(幸好我首先看了jstl使用資源文件的方法)
16,一個頁面兩個以上的表格. 很簡單,只須要每一個表格配置不一樣的id.
17,表格裏面還有表格. 很簡單.只要在外層表的 <dispaly:column> ( 在這加<display:table ...>。。。 </display:table>便可) </display:column> 18,表頭表尾 很簡單:<dispaly:caption><display:footer>想<display:column>同樣使用就好了. 主要注意一下: <display:footer>內容必須是<tr>.....</tr>
19,表格裏的值截斷,與顯示空白. <display:column property="nullValue" nulls="false"/> <display:column property="longDescription" maxLength="10" style="whitespace: nowrap;"/> 簡單得很.
ok,差很少到了關鍵的時候了。!!!!!
============================================= 關鍵: 20,如何分頁. 由於displaytag的分頁機制須要一次把全部紀錄都傳到裏面.因此對紀錄不少的項目並不合適.若是還非得用 displaytag那隻好放棄他的一些功能了.比較理智的方法是僅僅讓displaytag得到一頁的list.這樣就不用displaytag 的分頁index,而使用本身的,或者寫customertag,或者使用jsppager tag.
有不少人質疑這種方法,由於這使得displaytag的光芒至少減小了一半以上,由於他的不少功能所以而沒法使用, 例如排序功能,能夠針對全部list進行全局排序,若是每次只傳給一頁的數據,全局排序就和當頁排序沒有區別了. displaytag的全局排序功能宣佈廢掉了.
<display:table name="mylist" offset="m" length="n"/>這樣的功能基本上也沒有什麼用處。
那麼還使用它幹什麼呢? displaytag即便廢掉了一些武功仍然有它的優勢.例如 1,支持表格的嵌套. 2,支持css這樣就能寫少許地代碼使得程序更簡潔.只好定義好一套css,就能全局範圍內使用了. 3,另外還支持截斷長的字符串,這樣就不用在頁面使用本身的方法了. 4,可以實現比較複雜的邏輯從而產生動態連接。這也勉強因此個好處吧。 5,能輕鬆地使用struts的資源文件。使得它能夠很好的國際化。 6,可以過濾空值。
缺點: 1,分組就使用不了了,統計也沒法使用了。只統計當前頁是沒有意義的。 2,排序也變成當前頁排序了。沒多少意思。 3,導出也變成當前頁導出了,沒多少意思了。
其它功能
DisplayTag還有一些很實用的小功能,這裏提兩個。一個是對數據的Format,這是1.1版本添加的新功能,可使用標籤的方式格式化時間、數字、字符串。好比日期,在須要格式化的column標籤中添加format="",第一個參數爲格式化的數據序號,第二個參數是數據類型,數字爲 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的大小。具體怎麼用偶還沒研究。