中国人体摄影一区二区三区,www.视频在线.com,91麻豆精品国产91久久久更新资源速度超快 http://www.aygfsteel.com/19851985lili/category/18360.html?Give me hapy ? zh-cnThu, 29 May 2008 23:20:13 GMTThu, 29 May 2008 23:20:13 GMT60Struts使用Tiles輔助開發(fā)http://www.aygfsteel.com/19851985lili/articles/203787.html???MengChuChen???MengChuChenThu, 29 May 2008 04:31:00 GMThttp://www.aygfsteel.com/19851985lili/articles/203787.htmlhttp://www.aygfsteel.com/19851985lili/comments/203787.htmlhttp://www.aygfsteel.com/19851985lili/articles/203787.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/203787.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/203787.html
如果要看Tiles的詳細(xì)文檔,請訪問http://www.lifl.fr/~dumoulin/tiles/

在此我想從使用方式上說一下自己的經(jīng)驗:

往往我們的一個項目中,大部分的頁面的布局都是一樣的,這其中如果我們把一樣風(fēng)格的頁面歸為一類的話,這樣的分類就不會很多了。(不同的項目這樣的分類多少為有區(qū)別,要看頁面風(fēng)格規(guī)劃的是否高效)

假設(shè)我們提出一類頁面(如產(chǎn)品管理)的風(fēng)格,布局如下:
 
那么我們可以在tiles-defs.xml中定義這樣一個總的類型,如下:

tiles-defs.xml  放在/yourwebapp/WEB-INF/下

  1. <?xml version="1.0" encoding="ISO-8859-1" ?>
  2.  <!DOCTYPE tiles-definitions PUBLIC
  3.        "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
  4. "http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">
  5. <tiles-definitions>
  6.       <!―布局類型一 -->
  7.          <definition name="mainLayout" path="/homepage.jsp">
  8.          <put name="top"  value="/header.jsp" />
  9.          <put name="menu"    value="/menu.jsp"/>
  10.          <put name="main" value="/main.jsp" />
  11.          <put name="footer" value="/footer.jsp" />   
  12.   </definition>
  13.        ……
  14.        <!―布局類型二 -->
  15.   <definition>
  16.               ……
  17.   </definition>
  18.        ……
  19. </tiles-definitions>


以上定義了一種布局類型,假設(shè)命名為A布局,下面要列舉兩個屬于該類型風(fēng)格的頁面的布局方法添加產(chǎn)品頁面,最終我們要關(guān)心的時addProducts.jsp這個頁面,但是我們?nèi)绾问褂肁布局的布局風(fēng)格呢?

如下:

……接上tiles-defs.xml……

  1.       <!―布局類型A布局一 -->
  2.          <definition name="mainLayout" path="/homepage.jsp">
  3.          <put name="top"  value="/header.jsp" />
  4.          <put name="menu"    value="/menu.jsp"/>
  5.          <put name="main" value="/main.jsp" />
  6.          <put name="footer" value="/footer.jsp" />   
  7. </definition>
  8. <!―布局類型A布局“子類1:添加商品”一 -->
  9. <definition name=”mainLayout_products_add” extends=” mainLayout”>
  10.      <put name=”main” value=”/addProducts.jsp”/>
  11.      <!―相當(dāng)于把布局A中main的內(nèi)容換成我們需要的,其他保留 -->
  12. </definition>
  13. <!―布局類型A布局“子類2:查詢商品”一 -->
  14. <definition name=”mainLayout_products_search” extends=” mainLayout”>
  15.      <put name=”main” value=”/searchProducts.jsp”/>
  16. <!―相當(dāng)于把布局A中main的內(nèi)容換成我們需要的,其他保留 -->
  17. </definition>
  18. ……
  19. ……


以上只是以一種布局類型來說明,其他的布局類型(如:布局B,布局C。。。。。)都用相通的方法擴展,沒有什么難的地方。

下面簡要說一些tiles在struts-config.xml中的配置,在struts1.1種tiles是利用struts的擴展機制來完成裝載的,代碼很簡單如下:

  1. //struts-config.xml
  2.   ……
  3.   <plug-in className="org.apache.struts.tiles.TilesPlugin" >
  4.     <set-property property="definitions-config" 
  5.                         value="/WEB-INF/tiles-defs.xml" />
  6.   </plug-in>


如果你些多個tiles配置文件,那么用“,”號隔開。
下面在舉一個使用tiles以后action mapping 的寫法

如我們要進行添加商品的請求,在添加頁面里要先進行商品類型的裝載:

addProductAction.do――〉ProductAction――〉addProducts.jsp
ProductAction完成商品類型的集合返回client端
  1. //Struts-config.xml
  2. …………
  3.        <action path=”/ addProductAction”
  4.                      type=”com.***. ProductAction”>
  5.         <!―成功以后返回布局A子類1-- >
  6.        <forward name=”” path=” mainLayout_products_add”>
  7. </action>
  8. …………


好了,以上對一個操作的流程采用tiles以后的寫法進行了簡要的說明,具體Tiles的文檔請參看上面給出的連接。

Struts發(fā)布包里也有tilse的文檔和例子。


???MengChuChen 2008-05-29 12:31 發(fā)表評論
]]>
為Struts應(yīng)用配置web.xml文件 http://www.aygfsteel.com/19851985lili/articles/98469.html???MengChuChen???MengChuChenWed, 07 Feb 2007 00:23:00 GMThttp://www.aygfsteel.com/19851985lili/articles/98469.htmlhttp://www.aygfsteel.com/19851985lili/comments/98469.htmlhttp://www.aygfsteel.com/19851985lili/articles/98469.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/98469.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/98469.html閱讀全文

???MengChuChen 2007-02-07 08:23 發(fā)表評論
]]>
Struts框架http://www.aygfsteel.com/19851985lili/articles/97670.html???MengChuChen???MengChuChenFri, 02 Feb 2007 12:51:00 GMThttp://www.aygfsteel.com/19851985lili/articles/97670.htmlhttp://www.aygfsteel.com/19851985lili/comments/97670.htmlhttp://www.aygfsteel.com/19851985lili/articles/97670.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/97670.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/97670.html本章詳細(xì)討論struts架構(gòu)。我們將看到struts是如何清晰地區(qū)分控制,事務(wù)邏輯和外觀,從而簡化了開發(fā)應(yīng)用程序過程的。我們還將介紹struts提供的類如何使得開發(fā)工作更加簡單,這些類包括:
l 控制程序流程的類
l 實現(xiàn)和執(zhí)行程序事務(wù)邏輯的類
l 自定義的標(biāo)記庫使得創(chuàng)建和驗證HTML表單更加容易
1. Struts壓縮包內(nèi)容
文件夾jakarta-struts-1.0.2包含兩個目錄,lib和webapps。在lib目錄中有使用struts創(chuàng)建應(yīng)用程序是所需的文件:
文件 描述
jdbc2_0-stdext.jar 包含JDBC2.0 Optional Package API類。如果我們要使用struts提供的數(shù)據(jù)資源,就需要將這個文件拷貝到WEB-INF\lib下
Struts.jar 包含struts中所有的java類。同樣也需要拷貝到WEB-INF\lib下
*.tld 標(biāo)記庫描述器文件,描述了多個struts標(biāo)記庫中的自定義標(biāo)記。同樣要拷貝到WEB-INF\lib下
在webapps目錄下有如下文件:
Web應(yīng)用程序 描述
Struts-blank.war 一個簡單的web應(yīng)用程序
Struts-documentation.war 包含struts站點上所有struts文檔
Struts-example.war Struts很多特性的示范
Struts-exercisetaglib.war 主要用于對自定義標(biāo)簽庫進行增加而使用的測試頁,但也可以示范如何使用struts標(biāo)記
Struts-template.war 包含struts模板標(biāo)記的介紹和范例
Struts-upload.war 一個簡單的例子,示范如何使用struts框架上傳文件
2.Struts體系結(jié)構(gòu)
讓我們從MVC角度觀察struts框架中的組件

框架中三個部分:模型,視窗和控制器。
模型
在struts框架中,模型分為兩個部分:
l 系統(tǒng)的內(nèi)部狀態(tài)
l 可以改變狀態(tài)的操作(事務(wù)邏輯)
??內(nèi)部狀態(tài)通常由一組ActinForm JavaBean表示。根據(jù)設(shè)計或應(yīng)用程序復(fù)雜度的不同,這些Bean可以是自包含的并具有持續(xù)的狀態(tài),或只在需要時才獲得數(shù)據(jù)(從某個數(shù)據(jù)庫)。
??大型應(yīng)用程序通常在方法內(nèi)部封裝事務(wù)邏輯(操作),這些方法可以被擁有狀態(tài)信息的bean調(diào)用。比如購物車bean,它擁有用戶購買商品的信息,可能還有checkOut()方法用來檢查用戶的信用卡,并向倉庫發(fā)定貨信息。
??小型程序中,操作可能會被內(nèi)嵌在Action類,它是struts框架中控制器角色的一部分。當(dāng)邏輯簡單時這個方法很適合。
??建議用戶將事務(wù)邏輯(要做什么)與Action類所扮演的角色(決定做什么)分開。
視窗
??由JSP建立,struts包含擴展自定義標(biāo)簽庫,可以簡化創(chuàng)建完全國際化用戶界面的過程。
控制器
??struts中,基本的控制器組件是ActionServlet類中的實例servelt,實際使用的servlet在配置文件中由一組映射(由ActionMapping類進行描述)進行定義。
3.Struts框架中的組件
??
(由于ROSE工具還未能下載,只能找來這幅圖,它說明了一定問題,特別是ActionErrors,但它并沒有將ActionMapping,JSP和Tag Library包含進來,有時間作完替換)
框架中所使用的組件:
ActionServlet 控制器
ActionClass 包含事務(wù)邏輯
ActionForm 顯示模塊數(shù)據(jù)
ActionMapping 幫助控制器將請求映射到操作
ActionForward 用來指示操作轉(zhuǎn)移的對象
ActionError 用來存儲和回收錯誤
Struts標(biāo)記庫 可以減輕開發(fā)顯示層次的工作
下面我們看看各自在框架中所扮演的角色和責(zé)任。
3.1 Struts配置文件
這是將struts組件結(jié)合在一起的東東:struts-config.xml。默認(rèn)值
\WEB-INF\struts-config.xml。配置文件可以定義:
l 全局轉(zhuǎn)發(fā)
l ActionMapping類
l ActionForm bean
l JDBC數(shù)據(jù)源
配置全局轉(zhuǎn)發(fā)
全局轉(zhuǎn)發(fā)用來在JSP頁之間創(chuàng)建邏輯名稱映射。轉(zhuǎn)發(fā)都可以通過對調(diào)用操作映射的實例來獲得,例如:
actionMappingInstace.findForward(“l(fā)ogicalName”);
全局轉(zhuǎn)發(fā)的例子:(所有的例子我沒有進行解釋,一是結(jié)合表可以理解,二是例子大部分來自系列四的示例,你應(yīng)該在作完實驗后,再來看一便)
<global-forwards>
<forward?? name="bookCreated"??path="/BookView.jsp"/>
</global-forwards>
屬性 描述
Name 全局轉(zhuǎn)發(fā)的名字
Path 與目標(biāo)URL的相對路徑

配置ActionMapping
ActionMapping對象幫助進行框架內(nèi)部的流程控制,它們可將請求URI映射到Action類,并且將Action類與ActionForm bean相關(guān)聯(lián)。ActionServlet在內(nèi)部使用這些映射,并將控制轉(zhuǎn)移到特定Action類的實例。所有Action類使用perform()方法實現(xiàn)特定應(yīng)用程序代碼,返回一個ActionForward對象,其中包括響應(yīng)轉(zhuǎn)發(fā)的目標(biāo)資源名稱。例如:
<action-mappings>
<action??path=
"/createBook"
???????????? type=
"BookAction"
???????????? name=
"bookForm"
???????????? scope=
"request"
???????????? input=
"/CreateBook.jsp">
</action>
<forward name=”failure” path=”/CreateBook.jsp”/>
<forward name=”cancel” path=”/index.jsp”/>
</action-mappings>
屬性 描述
Path Action類的相對路徑
Name 與本操作關(guān)聯(lián)的Action bean的名稱
Type 連接到本映射的Action類的全稱(可有包名)
Scope ActionForm bean的作用域(請求或會話)
Prefix 用來匹配請求參數(shù)與bean屬性的前綴
Suffix 用來匹配請求參數(shù)與bean屬性的后綴
attribute 作用域名稱。
className ActionMapping對象的類的完全限定名默認(rèn)的類是org.apache.struts.action.ActionMapping
input 輸入表單的路徑,指向bean發(fā)生輸入錯誤必須返回的控制
unknown 設(shè)為true,操作將被作為所有沒有定義的ActionMapping的URI的默認(rèn)操作
validate 設(shè)置為true,則在調(diào)用Action對象上的perform()方法前,ActionServlet將調(diào)用ActionForm bean的validate()方法來進行輸入檢查
通過<forward>元素,可以定義資源的邏輯名稱,該資源是Action類的響應(yīng)要轉(zhuǎn)發(fā)的目標(biāo)。
屬性 描述
Id ID
ClassName ActionForward類的完全限定名,默認(rèn)是org.apache.struts.action.ActionForward
Name 操作類訪問ActionForward時所用的邏輯名
Path 響應(yīng)轉(zhuǎn)發(fā)的目標(biāo)資源的路徑
redirect 若設(shè)置為true,則ActionServlet使用sendRedirect()方法來轉(zhuǎn)發(fā)資源

配置ActionForm Bean
ActionServlet使用ActionForm來保存請求的參數(shù),這些bean的屬性名稱與HTTP請求參數(shù)中的名稱相對應(yīng),控制器將請求參數(shù)傳遞到ActionForm bean的實例,然后將這個實例傳送到Action類。例子:
<form-beans>
<form-bean name=
"bookForm" type="BookForm"/>
</form-beans>
屬性 描述
Id ID
className ActionForm bean的完全限定名,默認(rèn)值是org.apache.struts.action.ActionFormBean
Name 表單bean在相關(guān)作用域的名稱,這個屬性用來將bean與ActionMapping進行關(guān)聯(lián)
Type 類的完全限定名

配置JDBC數(shù)據(jù)源
用<data-sources>元素可以定義多個數(shù)據(jù)源。
屬性 描述
Id ID
Key Action類使用這個名稱來尋找連接
Type 實現(xiàn)JDBC接口的類的名稱
下面屬性需要<set-property>元素定義,在框架1.1版本中已不在使用,但你可用<data-source>元素。例子:
<data-sources>
<data-source id=”DS1”
key=”conPool”
????type=”org.apache.struts.util.GenericDataSource”
<set-property id=”SP1”
autoCommit=
"true"
description=
"Example Data Source Configuration"
driverClass=
"org.test.mm.mysql.Driver"
maxCount=
"4"
minCount=
"2"
url=
"jdbc:mysql://localhost/test"
user=
"struts"
password=
"wrox" />
<data-source/>
</data-sources>
屬性 描述
desciption 數(shù)據(jù)源的描述
autoCommit 數(shù)據(jù)源創(chuàng)建的連接所使用的默認(rèn)自動更新數(shù)據(jù)庫模式
driverClass 數(shù)據(jù)源所使用的類,用來顯示JDBC驅(qū)動程序接口
loginTimeout 數(shù)據(jù)庫登陸時間的限制,以秒為單位
maxCount 最多能建立的連接數(shù)目
minCount 要創(chuàng)建的最少連接數(shù)目
password 數(shù)據(jù)庫訪問的密碼
readOnly 創(chuàng)建只讀的連接
User 訪問數(shù)據(jù)庫的用戶名
url JDBC的URL
通過指定關(guān)鍵字名稱,Action類可以訪問數(shù)據(jù)源,比如:
javax.sql.DataSource ds = servlet.findDataSource(“conPool”);
javax.sql.Connection con = ds.getConnection();

3.2 ActionServlet類
框架中的控制器組件是有org.apache.struts.action.ActionServlet類實現(xiàn)的,這個類是javax.servlet.http.HttpServlet類的擴展。
Struts controller基本功能是:
1. 截獲用戶的Http請求
2. 把這個請求映射到相應(yīng)的Action類,如果這是此類收到的第一個請求,將初始化實例并
緩寸。
3. 創(chuàng)建或發(fā)現(xiàn)一個ActionForm bean實例(看配置文件是否定義),然后將請求過程移植到
bean.
4. 調(diào)用Action實例的perform()方法并將ActioForm bean,Action Mapping對象,request
和response對象傳給它。
如:public ActionForword perform(ActionMapping mapping,
???????????????????????????????? ActionForm form,
???????????????????????????????? HttpServletRequest request,
???????????????????????????????? HttpServletResponse response)
5.perform返回一個ActionForword對象,此對象連接到相應(yīng)的jsp頁面.
ActionServlet配置
我們需要在web.xml中聲明ActionServlet,并且將它配置成啟動時進行加載。以下為可以配置的初始化參數(shù):
參數(shù) 默認(rèn)值 描述
application null 應(yīng)用程序的資源集合的類
bufferSize 4096 文件上傳的緩沖區(qū)大小
config /WEB-INF/struts-config.xml 配置文件的位置和名稱
content Text/html 默認(rèn)的內(nèi)容類型
debug 0 程序調(diào)試的級別
detail 0 程序調(diào)試細(xì)節(jié)的級別
factory null 消息資源工廠,用于國際化中解釋消息資源
formBean org.apache.struts.action.ActionFormBean 封裝ActionForm bean信息的類的名稱
forward org.apache.struts.action.ActionForward 封裝ActionForward對象信息的類的名稱
locale truetrue,將在用戶會話中存儲一個本地對象
mapping org.apache.struts.action.ActionForward 封裝ActionMapping信息的類的名稱
maxFileSize 250M 上傳文件的最大尺寸
multipartClass org.apache.struts.action.ActionForward 處理多部分請求的類的名稱
noCache False HTTP標(biāo)頭是否要設(shè)置為禁止緩寸
Null True 設(shè)置為true,對于無效的信息關(guān)鍵字將返回null
tempDir 作為一個servlet參數(shù)提供給程序的工作目錄 處理下載文件是使用的臨時工作目錄
validate True 是否使用新格式的配置文件
vallidating True 是否對配置文件進行有效性分析
大多數(shù)情況下,標(biāo)準(zhǔn)的servlet就能夠滿足用戶需要。
第一次收到特定請求的URI時,ActionServlet將適當(dāng)?shù)腁ction類進行實例化,然后ActionServlet在Action類實例中以servlet為變量名存儲一個引用。當(dāng)被實例化后,Action類會被暫存以備再用。
ActionServlet也提供一些方法,由Action類用來訪問數(shù)據(jù)源和轉(zhuǎn)發(fā)目標(biāo)之類的資源。
ActionServlet方法
ActinServlet提供了一組能夠被Action對象使用的方法。
????Struts API的全部信息在struts-documentation.war中可以找到。動態(tài)的添加或刪除,這些方法只影響應(yīng)用程序當(dāng)前的實例:
publicvoid addFormBean(ActionFormBean formBean)
publicvoid removeFormBean(ActionFormBean formBean)
publicvoid addForward(ActionForward actionForward)
publicvoid removeForward(ActionForward actionForward)
publicvoid addMapping(ActionMapping actionMapping)
publicvoid removeMapping(ActionMapping actionMapping)
根據(jù)名稱查找對象:
public ActionFormBean findFormBean(String name)
public ActionForward findForward(String name)
public ActionMapping findMapping(String name)
用來處理數(shù)據(jù)源:
??publicvoid addDataSource(String key , DataSource ds)
??public DataSource findDataSource(String key)
我們還可以:
l 使用destroy()方法結(jié)束ActionServlet
l 使用reload()方法從struts配置文件將信息重新加載。

3.3 ActionMapping類
將特定請求映射到特定Action的相關(guān)信息存儲在ActionMapping中,ActionServelt將ActionMapping傳送到Action類的perform()方法,Action將使用ActionMapping的findForward()方法,此方法返回一個指定名稱的ActionForward,這樣Action就完成了本地轉(zhuǎn)發(fā)。若沒有找到具體的ActionForward,就返回一個null.
public ActionForward findForward(String name)
可在映射中動態(tài)添加ActionForward:
publicvoid addForward(ActionForward forward)
可返回與映射關(guān)聯(lián)的表單bean:
publicString getName()
可返回映射的屬性域(會話或請求)
??publicString getScope()

3.4 Action類
Action類真正實現(xiàn)應(yīng)用程序的事務(wù)邏輯,它們負(fù)責(zé)處理請求。在收到請求后,ActionServlet會:
l 為這個請求選擇適當(dāng)?shù)腁ction
l 如果需要,創(chuàng)建Action的一個實例
l 調(diào)用Action的perform()方法
如果ActionServlet不能找到有效的映射,它會調(diào)用默認(rèn)的Action類(在配置文件中定義)。如果找到了ActionServlet將適當(dāng)?shù)腁ctionMapping類轉(zhuǎn)發(fā)給Action,這個Action使用ActionMapping找到本地轉(zhuǎn)發(fā),然后獲得并設(shè)置ActionMapping屬性。根據(jù)servlet的環(huán)境和被覆蓋的perform()方法的簽名,ActionServlet也會傳送ServletRequest對象或HttpServletRequest對象。
所有Action類都擴展org.apache.struts.action.Action類,并且覆蓋類中定義的某一個perform()方法。有兩個perform()方法:
處理非HTTP(一般的)請求:
public ActionForward perform(ActionMapping action,
AcionForm form,
ServletRequest request,
ServletResponse response)
????throws IOException,ServletException
處理HTTP請求:
public ActionForward perform(ActionMapping action,
AcionForm form,
HttpServletRequest request,
HttpServletResponse response)
????throws IOException,ServletException
Action類必須以“線程安全”的方式進行編程,因為控制器會令多個同時發(fā)生的請求共享同一個實例,相應(yīng)的,在設(shè)計Action類時就需要注意以下幾點:
l 不能使用實例或靜態(tài)變量存儲特定請求的狀態(tài)信息,它們會在同一個操作中共享跨越請求的全局資源
l 如果要訪問的資源(如JavaBean和會話變量)在并行訪問時需要進行保護,那么訪問就要進行同步
Action類的方法
除了perform()方法外,還有以下方法:
可以獲得或設(shè)置與請求相關(guān)聯(lián)的區(qū)域:
public Locale getLocale(HttpServletRequest request)
publicvoid setLocale(HttpServletRequest request,Locale locale)
為應(yīng)用程序獲得消息資源:
public MessageResources getResources()
檢查用戶是否點擊表單上的“取消”鍵,如果是,將返回true:
public Boolean isCancelled(HttpServletRequest request)
當(dāng)應(yīng)用程序發(fā)生錯誤時,Action類能夠使用下面方法存儲錯誤信息:
publicvoid saveErrors(HttpServletRequest request,ActionErrors errors)
ActionError實例被用來存儲錯誤信息,這個方法在錯誤關(guān)鍵字下的請求屬性列表中存儲ActionError對象。通過使用在struts標(biāo)記庫中定義的自定義標(biāo)記,JSP頁能夠顯示這些錯誤信息,稍后我們就介紹。

3.5 ActionForm類
框架假設(shè)用戶在應(yīng)用程序中為每個表單都創(chuàng)建了一個ActionForm bean,對于每個在struts-config.xml文件中定義的bean,框架在調(diào)用Action類的perform()方法之前會進行以下操作:
l 在相關(guān)聯(lián)的關(guān)鍵字下,它檢查用于適當(dāng)類的bean實例的用戶會話,如果在會話中沒有可用的bean,它就會自動創(chuàng)建一個新的bean并添加到用戶的會話中。
l 對于請求中每個與bean屬性名稱對應(yīng)的參數(shù),Action調(diào)用相應(yīng)的設(shè)置方法。
l 當(dāng)Action perform()被調(diào)用時,最新的ActionForm bean傳送給它,參數(shù)值就可以立即使用了。
ActionForm類擴展org.apache.struts.action.ActionForm類,程序開發(fā)人員創(chuàng)建的bean能夠包含額外的屬性,而且ActionServlet可能使用反射(允許從已加載的對象中回收信息)訪問它。
ActionForm類提供了另一種處理錯誤的手段,提供兩個方法:
Public ActionErrors validate(ActionMappin mapping,
ServletRequest request)
Public ActionErrors validate(ActionMappin mapping,
HttpServletRequest request)
你應(yīng)該在自己的bean里覆蓋validate()方法,并在配置文件里設(shè)置<action>元素的validate為true。在ActionServlet調(diào)用Action類前,它會調(diào)用validate(),如果返回的ActionErrors不是null,則ActinForm會根據(jù)錯誤關(guān)鍵字將ActionErrors存儲在請求屬性列表中。
如果返回的不是null,而且長度大于0,則根據(jù)錯誤關(guān)鍵字將實例存儲在請求的屬性列表中,然后ActionServlet將響應(yīng)轉(zhuǎn)發(fā)到配置文件<action>元素的input屬性所指向的目標(biāo)。
如果需要執(zhí)行特定的數(shù)據(jù)有效性檢查,最好在Action類中進行這個操作,而不是在ActionForm類中進行。
方法reset()可將bean的屬性恢復(fù)到默認(rèn)值:
??publicvoid reset(ActionMapping mapping,HttpServletRequest request)
????publicvoid reset(ActionMapping mapping,ServletRequest request)
典型的ActionFrom bean只有屬性的設(shè)置與讀取方法(getXXX),而沒有實現(xiàn)事務(wù)邏輯的方法。只有簡單的輸入檢查邏輯,使用的目的是為了存儲用戶在相關(guān)表單中輸入的最新數(shù)據(jù),以便可以將同一網(wǎng)頁進行再生,同時提供一組錯誤信息,這樣就可以讓用戶修改不正確的輸入數(shù)據(jù)。而真正對數(shù)據(jù)有效性進行檢查的是Action類或適當(dāng)?shù)氖聞?wù)邏輯bean。

3.6 ActionForward類
目的是控制器將Action類的處理結(jié)果轉(zhuǎn)發(fā)至目的地。
Action類獲得ActionForward實例的句柄,然后可用三種方法返回到ActionServlet,所以我們可以這樣使用findForward():
l ActionServlet根據(jù)名稱獲取一個全局轉(zhuǎn)發(fā)
l ActionMappin實例被傳送到perform()方法,并根據(jù)名稱找到一個本地轉(zhuǎn)發(fā)
另一種是調(diào)用下面的一個構(gòu)造器來創(chuàng)建它們自己的一個實例:
public ActionForward()
public ActionForward(String path)
public ActionForward(String path,Boolean redirect)

3.7 錯誤處理
struts提供了兩個類來處理錯誤:ActionErrors和ActionError,它們都擴展org.apache.struts.action。ActionErrors保存著ActionError對象的集合,其中每一個代表了獨立的錯誤信息。每個ActionError都包含了關(guān)鍵字,能夠映射到資源文件中存儲的錯誤信息,而這個資源文件是在ActionServlet初始化參數(shù)中指定的。
ActionError類
ActionError類定義了一組重載的構(gòu)造器來創(chuàng)建錯誤信息,第一個構(gòu)造器方法使用一個字符串作為參數(shù),例如:
??????ActionError error = new ActionError(“error.Invalid”);
實例error映射到應(yīng)用程序資源文件中的一個錯誤消息:
??????error.invalid=<b>Invalid Number</b>
如果在JSP頁使用<html:error>,用戶就會看見加粗的Invalid Number。
另一種使用了java.text.MessageFormat類,可在消息中指定替換字符串,例如:
error.invalid=<b>Invalid Number{0}</b>
創(chuàng)建一個錯誤消息:
ActionError error = new ActionError(‘error.invalid’,new Double(-1));
JSP頁顯示:Invalild Number –1
????還有獲得特定消息的錯誤關(guān)鍵字:
publicString getKey()
????還有獲得替換字符串?dāng)?shù)組:
publicString[] getValues()

ActionError類
ActionError類從不獨立進行錯誤處理,它們總是被存儲在ActionErrors對象中。ActionErrors對象保存ActionError類的集合以及它們特定的屬性值,我們可以使用自己定義的屬性值,或是使用ActionErrors.GLOBAL_ERROR.
下面是典型Action類的perform()中錯誤處理情況:
MyForm form = (MyForm) form;
if (number == -1) {
ActionErrors errors = new ActionErrors();
ActionError error = new ActionError(“error.Invalid”,new Double(-1));
errors.add(ActionErrors.GLOBAL_ERROR,error);
saveErrors(req,errors);
String input = mapping.getInput();
Return new ActionForward(input);
??????}
ActionErrors有如下有用方法:
方法 描述
clear() 清除所有錯誤信息
empty() 如果ActionErrors對象是空的,它返回true
get() 返回錯誤信息。若無參數(shù),所有信息將作為一個Iterator對象返回
properties() 返回包含屬性名稱的Iterator,這些屬性至少有一個錯誤
size() 返回錯誤的數(shù)目(整型數(shù))












Struts標(biāo)記庫
4.Struts標(biāo)記庫
JSP視窗組件所使用的 struts標(biāo)記庫由四類標(biāo)記組成:
l Bean標(biāo)記:用來在JSP頁中管理bean
l 邏輯標(biāo)記:用來在JSP頁中控制流程
l HTML標(biāo)記:用來生成HTML標(biāo)記,在表單中顯示數(shù)據(jù),使用會話ID對URL進行編程
l 模板標(biāo)記:使用動態(tài)模板構(gòu)造普通格式的頁
4.1 Bean標(biāo)記
這個標(biāo)記庫中包含用于定義新bean、訪問bean及其屬性的標(biāo)記。Struts框架提供了多種自定義標(biāo)記用來在JSP頁中處理JavaBean。這些標(biāo)記被封裝在一個普通的標(biāo)記庫中,在文件struts-bean.tld中定義了它的標(biāo)記庫描述器。Bean標(biāo)記庫將標(biāo)記定義在四個子類別中:
l 創(chuàng)建和復(fù)制bean的標(biāo)記
l 腳本變量定義標(biāo)記
l bean翻譯標(biāo)記
l 消息國際化標(biāo)記
4.1.1 Bean復(fù)制標(biāo)記
可定義新bean,可復(fù)制現(xiàn)有bean,還可從現(xiàn)有bean復(fù)制屬性。
<bean:define>標(biāo)記用來:
l 定義新字符串常數(shù)
l 將現(xiàn)有的bean復(fù)制到新定義的bean對象
l 復(fù)制現(xiàn)有bean的屬性來創(chuàng)建新的bean
??<bean:define>標(biāo)記屬性:
??
屬性 描述
Id 新定義的bean腳本變量名稱,必須設(shè)置
Type 定義引入腳本變量的類
Value 為id屬性定義的腳本變量分配一個新的對象
Name 目標(biāo)bean的名稱。若value屬性沒有設(shè)置,這個屬性就必須設(shè)置
property Name屬性定義的bean的屬性名稱,用來定義新的bean
Scope 源bean的作用域。若沒有設(shè)置,搜索范圍是從頁作用域到應(yīng)用程序作用域
toScope 目標(biāo)bean的作用域。若沒有設(shè)置,默認(rèn)值是頁作用域
例如:定義一個bean:
<bean:define id=”test” value=”this is a test”/>
源bean在頁作用域中被拷貝大哦請求作用域中的另一個bean:
<bean:define id=”targetBean” name=”sourceBean”
scope=”page” toScope=”request”/>
4.1.2 定義腳本變量的標(biāo)記
從多種資源中定義和生成腳本變量,這些資源包括cookie,請求參數(shù),HTTP標(biāo)頭等等。屬性如下:
屬性 描述
Id 腳本變量和要定義的頁作用域?qū)傩缘拿Q
Name cookie/標(biāo)頭/參數(shù)的名稱
multiple 如果這個屬性設(shè)置了任意一個數(shù)值,所有匹配的cookie都會被積累并存儲到一個Cookie[](一個數(shù)組)類型的bean里。若無設(shè)置,指定cookie的第一個值將作為Cookie類型的值
Value 如果沒有匹配的cookie或數(shù)值,就返回這個屬性指定的默認(rèn)值
例如:
<bean:cookie id=”myCookie” name=”userName”/>
腳本變量名稱是myCookie,用來創(chuàng)建這個屬性的cookie的名稱是userName。
<bean:header id=”myHeader” name=”Accept-Language”/>
腳本變量名稱是myHeader,請求標(biāo)頭的名稱是Accept-Language.
<bean:parameter id=”myParameter” name=”myParameter”>
腳本變量名稱是myPatameter,它保存的請求參數(shù)的名稱也是myParameter.
<bean:include>標(biāo)記將對一個資源的響應(yīng)進行檢索,并引入一個腳本變量和字符串類型的頁作用域?qū)傩浴_@個資源可以是一個頁,一個ActionForward或一個外部URL。與<jsp:include>的不同是資源的響應(yīng)被存儲到一個頁作用域的bean中,而不是寫入到輸出流。屬性如下:
屬性 描述
Id 腳本變量和要定義的頁作用域?qū)傩缘拿Q
Page 一個內(nèi)部資源
forward 一個ActionForward
Href 要包含的資源的完整URL
例如:
<bean:include id=”myInclude” page=”MyJsp?x=1”/>
腳本變量的名稱是myInclude,要檢索的響應(yīng)來自資源MyJsp?x=1。

<bean:resource>標(biāo)記將檢索web應(yīng)用中的資源,并引入一個腳本變量和InputStream或字符串類型的頁作用域?qū)傩浴H绻跈z索資源時發(fā)生問題,就會產(chǎn)生一個請求時間異常。屬性如下:
屬性 描述
Id 腳本變量和要定義的頁作用域?qū)傩缘拿Q
Name 資源的相對路徑
Input 如果這個屬性不存在,資源的類型就是字符串
例如:
<bean:resource id=”myResource” name=”/WEB-INF/images/myResource.xml”/>
腳本變量的名稱是myResource,要檢索的資源的名稱是myResource.xml。

4.1.3 顯示Bean屬性
??標(biāo)記庫中定義了<bean:write>標(biāo)記,用來將bean的屬性輸送到封裝的JSP頁寫入器。這個標(biāo)記與<jsp:getProperty>類似,屬性如下:
屬性 描述
Name 要進行屬性顯示的bean的名稱
property 要顯示的屬性的名稱。如果這個屬性類有java.beans.PropertyEditor,getAsText()或toString 方法會被調(diào)用
Scope Bean的作用域,若沒有設(shè)置,搜索范圍是從頁到應(yīng)用程序作用域
Filter 如果設(shè)置true,屬性中的所有特殊HTML字符都將被轉(zhuǎn)化為相應(yīng)的實體引用
Ignore 如果設(shè)置false,當(dāng)發(fā)現(xiàn)屬性時會產(chǎn)生一個請求時間異常,否則返回null
例如:
<bean:write name=”myBean” property=”myProperty” scope=”request”
filter=”true”/>
myBean的屬性myProperty將會被顯示,作用域為請求,如果發(fā)現(xiàn)任何HTML特殊字符都將被轉(zhuǎn)化為相應(yīng)的實體引用。

4.1.4 消息標(biāo)記和國際化
strtus框架支持國際化和本地化。用戶在他們的計算機中定義自己所在的區(qū)域,當(dāng)web應(yīng)用程序需要輸出一條消息時,它將引用一個資源文件,在這個文件中所有的消息都使用了適當(dāng)?shù)恼Z言。一個應(yīng)用程序可能提供了很多資源文件,每個文件提供了用不同語言編寫的消息。如果沒有找到所選語言的資源文件,就將使用默認(rèn)的資源文件。
struts框架對國際化的支持是使用<bean:message>標(biāo)記,以及使用java.util數(shù)據(jù)包中定義的Locale和ResourceBundle類來實現(xiàn)Java2平臺對這些任務(wù)的支持。Java.text.MessageFormat類定義的技術(shù)可以支持消息的格式。利用此功能,開發(fā)人員不需了解這些類的細(xì)節(jié)就可進行國際化和設(shè)置消息的格式。
用strtus實現(xiàn)國際化和本地化:
第一步要定義資源文件的名稱,這個文件會包含用默認(rèn)語言編寫的在程序中會出現(xiàn)的所有消息。這些消息以“關(guān)鍵字-值”的形式存儲,如下:
error.validation.location = The entered location is invalid
這個文件需要存儲在類的路徑下,而且它的路徑要作為初始化參數(shù)傳送給ActionServlet作為參數(shù)進行傳遞時,路徑的格式要符合完整Java類的標(biāo)準(zhǔn)命名規(guī)范。比如,如果資源文件存儲在WEB-INF\classes目錄中,文件名是ApplicationResources.properties,那么需要傳遞的參數(shù)值是ApplicationResources。如果文件在WEB-INF\classes\com\test中,那么參數(shù)值就應(yīng)該是com.test. ApplicationResources.
為了實現(xiàn)國際化,所有的資源文件必須都存儲在基本資源文件所在的目錄中。基本資源文件包含的是用默認(rèn)地區(qū)語言-本地語言編寫的消息。如果基本資源文件的名稱是ApplicationResources.properties,那么用其他特定語言編寫的資源文件的名稱就應(yīng)該是ApplicationResources_xx.properties(xx為ISO編碼,如英語是en)。因此這些文件應(yīng)包含相同的關(guān)鍵字,但關(guān)鍵字的值是用特定語言編寫的。
ActionServlet的區(qū)域初始化參數(shù)必須與一個true值一起傳送,這樣ActionServlet就會在用戶會話中的Action.LOCALE_KEY關(guān)鍵字下存儲一個特定用戶計算機的區(qū)域?qū)ο蟆,F(xiàn)在可以運行一個國際化的web站點,它可以根據(jù)用戶計算機上的設(shè)置的區(qū)域自動以相應(yīng)的語言顯示。
我們還可以使用特定的字符串來替換部分消息,就象用java.text.MessageFormat的方法一樣:
error.invalid.number = The number {0} is valid
我們可以把字符串{0}替換成任何我們需要的數(shù)字。<bean:message>標(biāo)簽屬性如下:
屬性 描述
Key 資源文件中定義消息關(guān)鍵字
Locale 用戶會話中存儲的區(qū)域?qū)ο蟮膶傩悦Q。若沒有設(shè)置,默認(rèn)值是Action.LOCALE_KEY
Bundle 在應(yīng)用程序上下文中,存儲資源對象的屬性的名稱。如果沒有設(shè)置這個屬性,默認(rèn)值是Action.MESSAGE_KEY
arg0 第一個替換參數(shù)值
arg1 第二個替換參數(shù)值
arg2 第三個替換參數(shù)值
arg3 第四個替換參數(shù)值
例如:資源文件中定義了一個消息:
info.myKey = The numbers entered are {0},{1},{2},{3}
我們可使用下面的消息標(biāo)記:
<bean:message key=”info.myKey” arg0=”5” arg1=”6” arg2=”7” arg3=”8”/>
??這個信息標(biāo)記輸出到JSP頁會顯示為:The numbers entered are 5,6,7,8

4.2 邏輯標(biāo)記
邏輯庫的標(biāo)記能夠用來處理外觀邏輯而不需要使用scriptlet。Struts邏輯標(biāo)簽庫包含的標(biāo)記能夠有條件地產(chǎn)生輸出文本,在對象集合中循環(huán)從而重復(fù)地產(chǎn)生輸出文本,以及應(yīng)用程序流程控制。它也提供了一組在JSP頁中處理流程控制的標(biāo)記。這些標(biāo)記封裝在文件名為struts-logic.tld的標(biāo)記包中。邏輯標(biāo)記庫定義的標(biāo)記能夠執(zhí)行下列三個功能:
l 條件邏輯
l 重復(fù)
l 轉(zhuǎn)發(fā)/重定向響應(yīng)
4.2.1 條件邏輯
struts有三類條件邏輯。第一類可以比較下列實體與一個常數(shù)的大小:
l cookie
l 請求參數(shù)
l bean或bean的參數(shù)
l 請求標(biāo)頭
以下列出了這一類標(biāo)記:
標(biāo)記 功能
<equal> 如果常數(shù)與被定義的實體相等,返回true
<notEqual> 如果常數(shù)與被定義的實體不相等,返回true
<greaterEqual> 如果常數(shù)大于等于被定義的實體,返回true
<lessEqual> 如果常數(shù)小于等于被定義的實體,返回true
<lessThan> 如果常數(shù)小于被定義的實體,返回true
<greaterThan> 如果常數(shù)大于被定義的實體,返回true

這一類的所有標(biāo)記有相同的屬性
屬性 描述
Value 要進行比較的常數(shù)值
Cookie 要進行比較的HTTP cookie的名稱
Header 要進行比較的HTTP請求標(biāo)頭的名稱
parameter 要進行比較的HTTP請求參數(shù)的名稱
Name 如果要進行比較的是bean或bean的屬性,則這個屬性代表bean的名稱
property 要進行比較的bean屬性的名稱
Scope Bean的作用域,如果沒有指定作用域,則它的搜索范圍是從頁到應(yīng)用程序
例如:
<logic:equal parameter=”name” value=”SomeName”>
????????The entered name is SomeName
</logic:equal>
判斷名為”name”的請求參數(shù)的值是否是”SomeName”。
<logic:greaterThan name=”bean” property=”prop” scope=”page” value=”7”>
The value of bean.Prop is greater than 7
</logic:greaterThan>
判斷在頁的作用域中是否有一個名為”bean”的bean,它有一個prop屬性,這個屬性的值是否大于7。如果這個屬性能夠轉(zhuǎn)化為數(shù)值,就進行數(shù)值比較,否則就進行字符串比較。
第二類條件標(biāo)記定義了兩個標(biāo)記:
l <logic:present>
l <logic:notPresent>
它們的功能是在計算標(biāo)記體之前判斷特定的項目是否存在。標(biāo)記的屬性和屬性值決定了要進行檢查的項目。
屬性 描述
Cookie 由這個屬性指定的cookie將被檢查是否存在
Header 由這個屬性指定的請求標(biāo)頭將被檢查是否存在
parameter 由這個屬性指定的請求參數(shù)將被檢查是否存在
Name 如果沒有設(shè)置property屬性,那么有這個屬性指定的bean將被檢查是否存在。如果設(shè)置了,那么bean和bean屬性都將被檢查是否存在。
property 檢查有name屬性指定的bean中是否存在指定的屬性
Scope 如果指定了bean的名稱,這就是bean的作用域。如果沒有指定作用域,搜索的范圍從頁到應(yīng)用程序作用域。
Role 檢查當(dāng)前已經(jīng)確認(rèn)的用戶是否屬于特殊的角色
User 檢查當(dāng)前已經(jīng)確認(rèn)的用戶是否有特定的名稱
例如:
<logic:notPresent name=”bean” property=”prop” scope=”page”>
The bean property bean.prop is present
</logic:notPresent>
標(biāo)記判斷在頁作用域中是否存在一個名為”bean”的bean,這個bean有一個prop屬性。
第三類條件標(biāo)記比較復(fù)雜,這些標(biāo)記根據(jù)模板匹配的結(jié)果檢查標(biāo)記體的內(nèi)容。換句話說,這些標(biāo)記判斷一個指定項目的值是否是一個特定常數(shù)的子字符串:
l <logic:match>
l <logic:notMatch>
這些標(biāo)記允許JSP引擎在發(fā)現(xiàn)了匹配或是沒有發(fā)現(xiàn)時計算標(biāo)記主體。屬性如下:
屬性 描述
Cookie 要進行比較的HTTP cookie的名稱
Header 要進行比較的的HTTP標(biāo)頭 的名稱
parameter 要進行比較的的HTTP請求參數(shù)的名稱
Name 若要對bean或bean的屬性進行比較,這個屬性是用戶指定bean的名稱
location 如果設(shè)置了這個屬性的值,將會在這個指定的位置(索引值)進行匹配
scope 如果對bean進行比較,這個屬性指定了bean的作用域。如果沒有設(shè)置這個參數(shù),搜索范圍是從頁到應(yīng)用程序作用域
property 要進行比較的bean的屬性名稱
value 要進行比較的常數(shù)值
例如:
<logic:match parameter=”name” value=”xyz” location=”1”>
??????The parameter name is a sub-string of the string xyz from index 1
</logic:match>
標(biāo)記檢查名為”name”的請求參數(shù)是否是”xyz”的子字符串,但是子字符串必須從”xyz”的索引位置1開始(也就是說子字符串必須是”y”或”yz”)。
4.2.2 重復(fù)標(biāo)記
在邏輯標(biāo)記庫中定義了<logic:iterate>標(biāo)記,它能夠根據(jù)特定集合中元素的數(shù)目對標(biāo)記體的內(nèi)容進行重復(fù)的檢查。集合的類型可以是java.util.Iterator,java.util.Collection
,java.util.Map或是一個數(shù)組。有三種方法可以定義這個集合:
l 使用運行時間表達(dá)式來返回一個屬性集合的集合
l 將集合定義為bean,并且使用name屬性指定存儲屬性的名稱。
l 使用name屬性定義一個bean,并且使用property屬性定義一個返回集合的bean屬性。
當(dāng)前元素的集合會被定義為一個頁作用域的bean。屬性如下,所有這些屬性都能使用運行時表達(dá)式。
屬性 描述
collection 如果沒有設(shè)置name屬性,它就指定了要進行重復(fù)的集合
Id 頁作用域bean和腳本變量的名稱,它保存著集合中當(dāng)前元素的句柄
indexed 頁作用域JSP bean的名稱,它包含著每次重復(fù)完成后集合的當(dāng)前索引
Length 重復(fù)的最大次數(shù)
Name 作為集合的bean的名稱,或是一個bean名稱,它由property屬性定義的屬性,是個集合
Offset 重復(fù)開始位置的索引
property 作為集合的Bean屬性的名稱
Scope 如果指定了bean名稱,這個屬性設(shè)置bean的作用域。若沒有設(shè)置,搜索范圍從頁到應(yīng)用程序作用域
Type 為當(dāng)前定義的頁作用域bean的類型
例如:
<logic:iterate id=”currentInt”
collection=”<% =myList %>”
type=”java.lang.Integer”
offset=”1”
length=”2”>
????<% =currentint %>
????</logic:iterate>
代碼將從列表中的第一個元素開始重復(fù)兩個元素并且能夠讓當(dāng)前元素作為頁作用域和java.lang.Integer類型的腳本變量來使用。也就是說,如果myList包含元素1,2,3,4等,代碼將會打印1和2。
4.2.3 轉(zhuǎn)發(fā)和重定向標(biāo)記
轉(zhuǎn)發(fā)標(biāo)記
<logic:forward>標(biāo)記能夠?qū)㈨憫?yīng)轉(zhuǎn)發(fā)給重定向到特定的全局ActionForward上。ActionForward的類型決定了是使用PageContext轉(zhuǎn)發(fā)響應(yīng),還是使用sendRedirect將響應(yīng)進行重定向。此標(biāo)記只有一個”name”屬性,用來指定全局ActionForward的名稱,例如:
<logic:forward name=”myGlobalForward”/>
重定向標(biāo)記
<logic:redirect>標(biāo)記是一個能夠執(zhí)行HTTP重定向的強大工具。根據(jù)指定的不同屬性,它能夠通過不同的方式實現(xiàn)重定向。它還允許開發(fā)人員指定重定向URL的查詢參數(shù)。屬性如下:
屬性 描述
Forward 映射了資源相對路徑的ActionForward
Href 資源的完整URL
Page 資源的相對路徑
Name Map類型的頁名稱,請求,會話或程序?qū)傩缘拿Q,其中包含要附加大哦重定向URL(如果沒有設(shè)置 property屬性)上的“名稱-值”參數(shù)。或是具有Map類型屬性的bean名稱,其中包含相同的信息(沒有設(shè)置property屬性)
Property Map類型的bean屬性的名稱。Bean的名稱由name屬性指定。
Scope 如果指定了bean的名稱,這個屬性指定搜索bean的范圍。如果沒有設(shè)置,搜索范圍從頁到應(yīng)用程序作用域
ParamID 定義特定查詢參數(shù)的名稱
ParamName 字符串類型的bean的名稱,其中包含查詢參數(shù)的值(如果沒有設(shè)置paramProperty屬性);或是一個bean的名稱,它的屬性(在paramProperty屬性中指定)包含了查詢參數(shù)值
paramProperty 字符串bean屬性的名稱,其中包含著查詢參數(shù)的值
ParamScope ParamName定義的bean的搜索范圍
使用這個標(biāo)記時至少要指定forward,href或page中的一個屬性,以便標(biāo)明將響應(yīng)重定向到哪個資源。
4.3 HTML標(biāo)記
Struts HTML標(biāo)記可以大致地分為以下幾個功能:
l 顯示表單元素和輸入控件
l 顯示錯誤信息
l 顯示其他HTML元素
4.3.1 顯示表單元素和輸入控件
struts將HTML表單與為表單操作而定義的ActionForm bean緊密聯(lián)系在一起。表單輸入字段的名稱與ActionForm bean里定義的屬性名稱是對應(yīng)的。當(dāng)?shù)谝淮物@示表單時,表單的輸入字段是從ActionForm bean中移植過來的,當(dāng)表單被提交時,請求參數(shù)將移植到ActionForm bean實例。
所有可以在<form>標(biāo)記中使用的用來顯示HTML輸入控件的內(nèi)嵌標(biāo)記都使用下列屬性來定義JavaScript事件處理器。
屬性 描述
Onblur 字段失去了焦點
Onchange 字段失去了焦點并且數(shù)值被更改了
Onclick 字段被鼠標(biāo)點擊
Ondblclick 字段被鼠標(biāo)雙擊
Onfocus 字段接收到輸入焦點
Onkeydown 字段擁有焦點并且有鍵按下
onkeypress 字段擁有焦點并且有鍵按下并釋放
Onkeyup 字段擁有焦點并且有鍵被釋放
onmousedown 鼠標(biāo)指針指向字段并且點擊
onmousemove 鼠標(biāo)指針指向字段并且在字段內(nèi)移動
onmouseout 鼠標(biāo)指針指向控件,但是指針在元素外圍移動
onmouseover 鼠標(biāo)指針沒有指向字段,但是指針在元素內(nèi)部移動
Onmouseup 鼠標(biāo)指針指向字段,并且釋放了鼠標(biāo)按鍵
<form>元素中能夠被定義的其他一般屬性有:
屬性 描述
Accesskey 定義訪問輸入字段的快捷鍵
Style 定義輸入字段的樣式
styleClass 定義輸入字段的樣式表類
Tabindex 輸入字段的tab順序
表單標(biāo)記
<html:form>標(biāo)記用來顯示HTML標(biāo)記,可以指定AcitonForm bean的名稱和它的類名。如果沒有設(shè)置這些屬性,就需要有配置文件來指定ActionMapping以表明當(dāng)前輸入的是哪個JSP頁,以及從映射中檢索的bean名和類。如果在ActionMapping指定的作用域中沒有找到指定的名稱,就會創(chuàng)建并存儲一個新的bean,否則將使用找到的bean。
<form>標(biāo)記能夠包含與各種HTML輸入字段相對應(yīng)的子標(biāo)記。
<html:form>標(biāo)記屬性如下:
屬性 描述
Action 與表單相關(guān)的操作。在配置中,這個操作也用來標(biāo)識與表單相關(guān)的ActionForm bean
Enctype 表單HTTP方法的編碼類型
Focus 表單中需要初始化焦點的字段
Method 表單使用的HTTP方法
Name 與表單相關(guān)的ActionForm bean的名稱。如果沒有設(shè)置這個屬性,bean的名稱將會從配置信息中獲得
Onreset 表單復(fù)位時的JavaScript事件句柄
Onsubmit 表單提交時的JavaScript事件句柄
Scope 搜索ActionForm bean的范圍。如果沒有設(shè)置,將從配置文件中獲取
Style 使用的格式
styleClass 這個元素的格式表類
Type ActionForm bean的完整名稱。如果沒有設(shè)置,將從配置文件獲得
例如:
<html:form action=”validateEmploee.do” method=”post”>
</html:form>
與表單相關(guān)的操作路徑是validateEmployee,而表單數(shù)據(jù)是通過POST傳遞的。對于這個表單來說,ActionForm bean的其他信息,如bean名稱類型,作用域,都是從表單指定操作的ActionMapping中檢索得到的:
<form-beans>
<form-bean name=”empForm” type=”com.example.EmployeeForm”/>
????</form-beans>
????<action-mappings>
????<action path=”/validateEmployee”
type=”com.example.ValidateExampleAction”
name=”empForm”
scope=”request”
input=”/employeeInput.jsp”>
<forward name=”success” path=”/employeeOutput.jsp”>
???? </action>
????</action-mapping>
如果配置文件中包含上述信息,并且請求URI的*.do被映射到ActionServlet,與表單相關(guān)的ActionForm bean的名稱,類型和作用域分別是empForm,com.example.EmployeeForm和request.這些屬性也可以使用<html:form>標(biāo)記屬性進行顯示的定義。
以下標(biāo)記必須嵌套在<html:form>標(biāo)記里
按鈕和取消標(biāo)記
<html:button>標(biāo)記顯示一個按鈕控件;<html:cancel>標(biāo)記顯示一個取消按鈕。屬性如下:
屬性 描述
Property 定義在表單被提交時返回到服務(wù)器的請求參數(shù)的名稱
Value 按鈕上的標(biāo)記
復(fù)位和提交標(biāo)記
<html:reset>和<html:submit>標(biāo)記分別能夠顯示HTML復(fù)位按鈕和提交按鈕。
文本和文本區(qū)標(biāo)記
<html:text>和<html:textarea>標(biāo)記分別HTML文本框和文本區(qū),屬性如下:
屬性 描述
Property 定義當(dāng)表單被提交時送回到服務(wù)器的請求參數(shù)的名稱,或用來確定文本元素當(dāng)前值的bean的屬性名稱
Name 屬性被查詢的bean的名稱,它決定了文本框和文本區(qū)的值。如果沒有設(shè)置,將使用與這個內(nèi)嵌表單相關(guān)的ActionForm的名稱
<html:text>標(biāo)記還有以下屬性:
屬性 描述
Maxlength 能夠輸入的最大字符數(shù)
Size 文本框的大小(字符數(shù))
<html:textarea>標(biāo)記特有的屬性如下:
屬性 描述
Rows 文本區(qū)的行數(shù)
Cols 文本區(qū)的列數(shù)
檢查框和復(fù)選框標(biāo)記
<html:checkbox>標(biāo)記能夠顯示檢查框控件。<html:multibox>標(biāo)記能夠顯示HTML復(fù)選框控件,請求對象在傳遞檢查框名稱時使用的getParameterValues()調(diào)用將返回一個字符串?dāng)?shù)組。屬性如下:
屬性 描述
Name Bean的名稱,其屬性會被用來確定檢查是否以選中的狀態(tài)顯示。如果沒有設(shè)置,將使用與這個內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。
Property 檢查框的名稱,也是決定檢查框是否以選中的狀態(tài)顯示的bean屬性名稱。在復(fù)選框的情況下,這個屬性必須是一個數(shù)組。
Value 當(dāng)檢查框被選中時返回到服務(wù)器的請求參數(shù)的值
例如:
<html:checkbox property=”married” value=”Y”/>
一個名為married的檢查框,在表單提交時會返回一個”Y”.
文件標(biāo)記
<html:file>標(biāo)記可以顯示HTML文件控件。屬性如下:
屬性 描述
Name Bean的名稱,它的屬性將確定文件控件中顯示的內(nèi)容。如果沒設(shè)置,將使用與內(nèi)嵌表單相關(guān)的ActionForm bean的名稱
property 這個屬性定義了當(dāng)表單被提交時送回到服務(wù)器的請求參數(shù)的名稱,以及用來確定文件控件中顯示內(nèi)容的bean屬性名稱
Accept 服務(wù)器能夠處理的內(nèi)容類型集。它也將對客戶瀏覽器對話框中的可選文件類型進行過濾
Value 按鈕上的標(biāo)記,這個按鈕能夠在本地文件系統(tǒng)中瀏覽文件
單選鈕標(biāo)記
<html:radio>標(biāo)記用來顯示HTML單選鈕控件,屬性如下:
屬性 描述
Name Bean的名稱,其屬性會被用來確定單選鈕是否以選中的狀態(tài)顯示。如果沒有設(shè)置,將使用與這個內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。
property 當(dāng)表單被提交時送回到服務(wù)器的請求參數(shù)的名稱,以及用來確定單選鈕是否以被選中狀態(tài)進行顯示的bean屬性的名稱
Value 當(dāng)單選鈕被選中時返回到服務(wù)器的值
隱藏標(biāo)記
<html:hidden>標(biāo)記能夠顯示HTML隱藏輸入元素,屬性如下:
屬性 描述
Name Bean的名稱,其屬性會被用來確定隱藏元素的當(dāng)前值。如果沒有設(shè)置,將使用與這個內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。
property 定義了當(dāng)表單被提交時送回到服務(wù)器的請求參數(shù)的名稱,以及用來確定隱藏元素當(dāng)前值的bean屬性的名稱
Value 用來初始化隱藏輸入元素的值
密碼標(biāo)記
<html:password>標(biāo)記能夠顯示HTML密碼控件,屬性如下:
屬性 描述
maxlength 能夠輸入的最大字符數(shù)
Name Bean的名稱,它的屬性將用來確定密碼元素的當(dāng)前值。如果沒有設(shè)置,將使用與這個內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。
property 定義了當(dāng)表單被提交時送回到服務(wù)器的請求參數(shù)的名稱,以及用來確定密碼元素當(dāng)前值的bean屬性的名稱
redisplay 在顯示這個字段時,如果相應(yīng)的bean屬性已經(jīng)被設(shè)置了數(shù)據(jù),這個屬性決定了是否顯示密碼的內(nèi)容
Size 字段的大小
選擇標(biāo)記
<html:select>標(biāo)記能夠顯示HTML選擇控件,屬性如下:
屬性 描述
multiple 表明這個選擇控件是否允許進行多選
Name Bean的名稱,它的屬性確定了哪個。如果沒有設(shè)置,將使用與這個內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。
property 定義了當(dāng)表單被提交時送回到服務(wù)器的請求參數(shù)的名稱,以及用來確定哪個選項需要被選中的bean屬性的名稱
Size 能夠同時顯示的選項數(shù)目
Value 用來表明需要被選中的選項
選項標(biāo)記(這個元素需要嵌套在<html:select>標(biāo)記里)
<html:option>標(biāo)記用來顯示HTML選項元素集合,屬性如下:
屬性 描述
collection Bean集合的名稱,這個集合存儲在某個作用域的屬性中。選項的數(shù)目與集合中元素的數(shù)目相同。Property屬性能夠定義選項值所使用的bean屬性,而labelProperty屬性定義選項標(biāo)記所使用的bean的屬性
labelName 用來指定存儲于某個作用域的bean,這個bean是一個字符串的集合,能夠定義<html:option>元素的標(biāo)記(如果標(biāo)志與值不相同)
labelProperty 與collection屬性共同使用時,用來定義了存儲于某個作用域的bean,這個bean將返回一個字符串集合,能夠用來寫入<html:option>元素的value屬性
Name 如果這是唯一被指定的屬性,它就定義了存儲于某個作用域的bean,這個bean將返回一個字符串集合,能夠用來寫入<html:option>元素的value屬性
property 這個屬性在與collection屬性共同使用時,定義了每個要顯示選項值的獨立bean的name屬性。如果不是與collection屬性共同使用,這個屬性定義了由name屬性指定的bean的屬性名稱(如果有name屬性),或是定義了一個ActionForm bean,這個bean將返回一個集合來寫入選項的值
我們看一下這個標(biāo)記的一些例子:
<html:option collection=”optionCollection” property=”optionValue”
labelProperty=”optionLabel”/>
標(biāo)記假設(shè)在某個作用域中有一個名為optionCollection的集合,它包含了一些具有optionValue屬性的獨立的bean,每個屬性將作為一個選項的值。每個選項的標(biāo)志由bean的optionLabel屬性屬性進行定義。
<html:option name=”optionValues” labelName=”optionLabels”/>
標(biāo)記中optionValues代表一個存儲在某個作用域中的bean,它是一個字符串集合,能夠用來寫入選項的值,而optionLabels代表一個存儲在某個作用域中的bean,它也是一個字符串集合,能夠用來寫入選項的標(biāo)志。
4.3.2 顯示錯誤信息的標(biāo)記
<html:errors>標(biāo)記能夠與ActionErrors結(jié)合在一起來顯示錯誤信息。這個標(biāo)記首先要從當(dāng)前區(qū)域的資源文件中讀取消息關(guān)鍵字errors.header,然后顯示消息的文本。接下去它會在ActionErrors對象(通常作為請求參數(shù)而存儲在Action.ERROR_KEY關(guān)鍵字下)中循環(huán),讀取單個ActionError對象的消息關(guān)鍵字,從當(dāng)前區(qū)域的資源文件中讀取并格式化相應(yīng)的消息,并且顯示它們。然后它讀取與errors.footer關(guān)鍵字相對應(yīng)的消息并且顯示出來。
通過定義property屬性能夠過濾要顯示的消息,這個屬性的值應(yīng)該與ActionErrors對象中存儲ActionError對象的關(guān)鍵字對應(yīng)。屬性如下:
屬性 描述
Bundle 表示應(yīng)用程序作用域?qū)傩缘拿Q,它包含著消息資源,其默認(rèn)值A(chǔ)cion.MESSAGE_KEY
Locale 表示會話作用域?qū)傩缘拿Q,它存儲著用戶當(dāng)前登錄的區(qū)域信息。其默認(rèn)值是Action.ERROR_KEY
Name 表示請求屬性的名稱,它存儲著ActionErrors對象。其默認(rèn)值是Action.ERROR_KEY
property 這個屬性指定了ActionErrors對象中存儲每個獨立ActionError對象的關(guān)鍵字,它可以過濾消息
例子:
<html:errors/>
顯示集合中所有的錯誤。
<html:errors property=”missing.name”/>
顯示存儲在missing.name關(guān)鍵字的錯誤。
4.3.3 其他HTML標(biāo)記
struts HTML標(biāo)記還定義了下列標(biāo)記來顯示其他HTML元素:
l <html:html> : 顯示HTML元素
l <html:img> : 顯示圖象標(biāo)記
l <html:link> : 顯示HTML鏈接或錨點
l <html:rewrite> : 創(chuàng)建沒有錨點標(biāo)記的URI
這些標(biāo)記的詳細(xì)內(nèi)容請參照struts文檔。
4.4 模板標(biāo)記
動態(tài)模板是模塊化WEB頁布局設(shè)計的強大手段。Struts模板標(biāo)記庫定義了自定義標(biāo)記來實現(xiàn)動態(tài)模板。
插入標(biāo)記
<template:insert>標(biāo)記能夠在應(yīng)用程序的JSP頁中插入動態(tài)模板。這個標(biāo)記只有一個template屬性,用來定義模板JSP頁。要插入到模板的頁是有多個<template:put>標(biāo)記來指定的,而這些標(biāo)記被定義為<template:insert>標(biāo)記的主體內(nèi)容。
放置標(biāo)記
<template:put>標(biāo)記是<template:insert>標(biāo)記內(nèi)部使用的,用來指定插入到模板的資源。屬性如下:
屬性 描述
content 定義要插入的內(nèi)容,比如一個JSP文件或一個HTML文件
direct 如果這個設(shè)置為true,由content屬性指定的內(nèi)容將直接顯示在JSP上而不是作為包含文件
Name 要插入的內(nèi)容的名稱
Role 如果設(shè)置了這個屬性,只有在當(dāng)前合法用戶具有特定角色時才能進行內(nèi)容的插入。
獲得標(biāo)記
在模板JSP頁中使用<template:get>標(biāo)記能夠檢索由<template:put>標(biāo)記插入到JSP頁的資源。屬性如下:
屬性 描述
Name 由<template:put>標(biāo)記插入的內(nèi)容的名稱
Role 如果設(shè)置了這個屬性,只有在當(dāng)前合法用戶具有特定角色時才能進行內(nèi)容的檢索
使用模板標(biāo)記
首先編寫一個模板JSP頁,它將被所有的web頁使用:
<html>
??<%@ taglib uri=”/template” prefix=”template” %>
??<head>
<title></title>
??</head>
??<body>
<table width=”100%” height=”100%” >
??<tr height=”10%”>
????<td>
??????<template:get name=”header”/>
????</td>
??</tr>
??<tr height=”80%”>
????<td>
??????<template:get name=”content”/>
????</td>
??</tr>
??<tr height=”10%”>
????<td>
??????<template:get name=”footer”/>
????</td>
??</tr>
</table>
??</body>
</html>
我們將這個文件命名為template.jsp。這個文件使用<template:get>標(biāo)記來獲得由JSP頁使用<template:put>標(biāo)記提供的內(nèi)容,并且將內(nèi)容在一個HTML表格中顯示出來。這三個內(nèi)容是標(biāo)題,內(nèi)容和頁腳。典型的內(nèi)容JSP會是這樣:
<%@ taglib uri=”/template” prefix=”/template” %>
<template:insert template=”template.jsp”>
??<template:put name=”header” content=”header.html”/>
??<template:put name=”content” content=”employeeList.jsp”/>
??<template:put name=”footer” content=”footer.html”/>
</template:insert>
這個應(yīng)用程序JSP頁使用<template:insert標(biāo)記來定義模板,然后使用<template:put>標(biāo)記將特定內(nèi)容名稱指定的資源放到模板JSP頁中。如果我們有上百個布局相同的頁


???MengChuChen 2007-02-02 20:51 發(fā)表評論
]]>
Struts時,如果要在JSP隱式的傳值給Action有兩種情況:http://www.aygfsteel.com/19851985lili/articles/97664.html???MengChuChen???MengChuChenFri, 02 Feb 2007 12:48:00 GMThttp://www.aygfsteel.com/19851985lili/articles/97664.htmlhttp://www.aygfsteel.com/19851985lili/comments/97664.htmlhttp://www.aygfsteel.com/19851985lili/articles/97664.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/97664.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/97664.html1、要傳的值是FromBean中的一個字段,你說的情況應(yīng)該就是這種情況,例如需要在Edit頁面中保存theID,在Action中執(zhí)行Update操作時根據(jù)ID來更新數(shù)據(jù)庫的值,你可以這樣做:
Jsp中的代碼為:<html:hidden property="theID" />
提交后,theID的值就會放到FormBean中的theID中,你就可以通過getTheID()來獲得這個值。
2、要傳的值不是FromBean中的一個字段:
Jsp中的代碼為:
<input type="hidden" name="XXX" value="<%=request.getAttribute(XXX)%>">
當(dāng)然,你應(yīng)該在Action中就已經(jīng)就這個值放到了request中,request.setAttribute("XXX",value);,
然后在Action中你才可以通過request.getParameter("XXX");來取得這個值。

補充一點,request.setAttribute("XXX",value);中,value應(yīng)該是個String,還有,<input type="hidden" name="XXX" value="<%=request.getAttribute(XXX)%>">應(yīng)該改為
<input type="hidden" name="XXX" value="<%=(String)request.getAttribute(XXX)%>">


???MengChuChen 2007-02-02 20:48 發(fā)表評論
]]>
struts實現(xiàn)多附件上傳 廣東精鷹軟件工作室(劉正仁) http://www.aygfsteel.com/19851985lili/articles/97645.html???MengChuChen???MengChuChenFri, 02 Feb 2007 12:34:00 GMThttp://www.aygfsteel.com/19851985lili/articles/97645.htmlhttp://www.aygfsteel.com/19851985lili/comments/97645.htmlhttp://www.aygfsteel.com/19851985lili/articles/97645.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/97645.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/97645.htmljsp頁面:

<%@ page contentType="text/html; charset=utf-8" %>
<%@include file="/common.jsp"%>
<html>
<head>
<title>
testArr
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head>
<body bgcolor="#ffffff">
<html:form action="/testArr.do"? enctype="multipart/form-data">
<input type="hidden" name="fileUpLoadNumberRow" id="fileUpLoadNumberRow" value="1">
?<table? <%=tableStyle%> id="testArr">
?<tr? class="ListTableHeader" >
???? <td width="13%"? align="center"><b>操作</b></td>
???? <td width="33%"? align="center"><b>文件描述</b></td>
? <td width="54%"? align="center"><b>源文件</b></td>
?</tr>
?<tr? class="ListTableRow" >
???? <td width="13%"> <input type="button" name="Submit" value="刪除" class="Button4"? onclick="delCode(1)"></td>
???? <td width="33%"? align="center"><b><input type="hidden" name="fileUpLoadHiddenIDNewObject1" value="" id="fileUpLoadHiddenIDNewObject1"><input type="text" name="fileTitle1" <%=input100Change%> id="fileTitle1"></b></td>
? <td width="54%"? align="center"><b><input type="file" name="filePath1"? <%=input100%> id="filePath1"? onchange="showFileChange(1,'filePath','fileUpLoadHiddenIDNewObject','fileTitle')"></b></td>
?</tr>
?<tr? class="ListTableRow" >
???? <td width="100%" colspan="3" ><input type="submit" name="Submit" value="提交" class="Button4">
???? <input type="button" name="Submit" value="新增附件" class="Button4"? onclick="addCode()">
??? </td>
?</tr>
?</table>
</html:form>
<script language="javascript" type="text/javascript">
String.prototype.trim = function()
{
??? return this.replace(/(^[\s]*)|([\s]*$)/g, "");
}
function addCode(){
? var objTable=document.all("testArr");
? var objTableLength=objTable.rows.length
? var objChild=document.all("fileUpLoadNumberRow");
? objChild.value=parseInt(objChild.value,10)+1;
? var myrow=objTable.insertRow(objTableLength-1);
? var mycell=myrow.insertCell();
? mycell.innerHTML="<input type='button' name='Submit' value='刪除' class='Button4' onClick='delCode("+(objTableLength-2+1)+")'>";

? mycell=myrow.insertCell();
? mycell.innerHTML="<input type='hidden' name='fileUpLoadHiddenIDNewObject"+objChild.value+"'? id='fileUpLoadHiddenIDNewObject"+objChild.value+"'><input type='text' name='fileTitle"+objChild.value+"' <%=input100Change%> id='fileTitle"+objChild.value+"'? value='' trim='true' dataType='Require'? msg='文件描述不能為空!'>";
? mycell=myrow.insertCell();
? var html=""
? html=html+"<input type='file' name='filePath"+objChild.value+"' <%=input100%> id='filePath"+objChild.value+"' onChange=showFileChange("+objChild.value+",'filePath','fileUpLoadHiddenIDNewObject','fileTitle')>";
? mycell.innerHTML=html

}
function delCode(rowNum)
{
? var objTable=document.all("testArr");
? if(window.confirm("真的要刪除所選項!"))
? {
???????? objTable.deleteRow(rowNum);
? }
? for(var i=1;i<objTable.rows.length-1;i++)
? {

???????? objTable.rows(i).cells(0).innerHTML="<input type='button' name='Submit' value='刪除' class='Button4' onClick='delCode("+i+")'>";

? }

}
function changeButtomHtml()
{

}

</script>
</body>
</html>

?

common.jsp???? 不要的代碼請去除

<!--引入系統(tǒng)中要用的標(biāo)簽-->

<%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@taglib uri="/WEB-INF/fireeagle.tld" prefix="fireeagle"%>
<!--引入系統(tǒng)中要用的類-->
<%@page import="java.util.*"%>
<%@page import="com.ytstm.frame.IConstants"%>
<%@page import="com.ytstm.util.*"%>

<%
? String baseURL = request.getContextPath();????? //得到當(dāng)前發(fā)布的根路經(jīng)
? Object objectRes=request.getAttribute("org.apache.struts.action.MESSAGE");? //得到struts當(dāng)前配置的資源文件
? org.apache.struts.util.MessageResources resources =(org.apache.struts.util.MessageResources)objectRes;
? String exitPro="";?????????????????????? //當(dāng)頁面處在修改狀態(tài)時的提示語
? String pageNum_fireeagle="";???????????? //翻頁時當(dāng)輸入的不是數(shù)字時的提示語
? if(resources!=null)
?{
? exitPro= resources.getMessage("exitPro");
? pageNum_fireeagle=resources.getMessage("pageNum");
?}

%>
<script language="javascript" type="text/javascript">
? var baseURL='<%=baseURL%>';??????? //得到當(dāng)前發(fā)布的根路經(jīng)
? var editModel_fireeagle=false;???? //用戶操作的當(dāng)前頁面的狀態(tài). true以修改數(shù)據(jù),false沒有修改數(shù)據(jù)
? var exitPro='<%=exitPro%>'???????? //當(dāng)頁面處在修改狀態(tài)時的提示語
? var pageNum_fireeagle='<%=pageNum_fireeagle%>'?? //翻頁時當(dāng)輸入的不是數(shù)字時的提示語
?</script>
<%
? //tableStyle? 表格的樣式,可以減少頁面的html代碼量
? String tableStyle="width=\"100%\"? border=\"1\" cellSpacing=\"0\" cellpadding=\"3\"?? bordercolorlight=\"#E2D7CF\" bordercolordark=\"#FAF8F6\"";
? String frame = baseURL + "/frame"; //框架模塊的前綴
? String project = baseURL + "/project";//項目立項模塊的前綴
? String contract = baseURL + "/contract";//合同模塊的前綴
? String process = baseURL + "/process";//過程模塊的前綴

? //input 的樣式和鍵盤按下事件,它會轉(zhuǎn)入到下一個可輸入控件,可以減少頁面的html代碼量
? String input="class='formStyleall' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input4="class='formStyleall' size='4' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
?? String input10="class='formStyleall' size='12' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input12="class='formStyleall' size='12' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input15="class='formStyleall' size='15' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input20="class='formStyleall' size='20' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input25="class='formStyleall' size='25' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input30="class='formStyleall' size='30' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input35="class='formStyleall' size='35' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input40="class='formStyleall' size='40' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input50="class='formStyleall' size='50' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
? String input60="class='formStyleall' size='60' onKeyDown='next_focus(this)' onChange='changeEditModel()'";
?? String input100="class='formStyleall' style='width=100%' onKeyDown='next_focus(this)'";
?? String input100Change="class='formStyleall' style='width=100%' onKeyDown='next_focus(this)' onChange='changeEditModel()'";

? //onchange事件的全局變量,這個方法用于修改用戶操作的當(dāng)前頁面的狀態(tài).
? String onChange="onChange='changeEditModel()'";
? String changeName="'changeEditModel()'";
? //給色*號標(biāo)示.和()標(biāo)示,可以減少頁面的html代碼量
? String red="&nbsp;&nbsp;<font color='red'><b>*</b></font>";
? String redLeft="<font color='#FF0000'>(</font>";
? String redRight="<font color='#FF0000'>)</font>";
? String orderTitle="style='cursor:hand'? align='center'";
? //查看,新增,修改.用在聯(lián)接?后面
? String modifyView=IConstants.FRAME_MODIFY_FLAG+"="+IConstants.FRAME_MODIFY_FLAG_VIEW;
? String modifyAdd=IConstants.FRAME_MODIFY_FLAG+"="+IConstants.FRAME_MODIFY_FLAG_ADD;
? String modifyEdit=IConstants.FRAME_MODIFY_FLAG+"="+IConstants.FRAME_MODIFY_FLAG_EDIT;

? //頁面退出是要執(zhí)行的方法,當(dāng)用戶修改了頁面內(nèi)容后退出頁面時,要給提示信息給用戶
? String onbeforeunload ="onbeforeunload='javacript:return(isClose())'";
? //屏蔽頁面的右鍵功能
// String disableCopy="ondragstart=self.event.returnValue=true onselectstart=self.event.returnValue=true oncontextmenu=self.event.returnValue=false";
String disableCopy="";
%>
<!--引入公用的js代碼-->
<script type="text/javascript" src="<%=baseURL%>/js/public.js"></script>
<!--引入公驗證的js代碼-->
<script type="text/javascript" src="<%=baseURL%>/js/validator.js"></script>
<script type="text/javascript" src="<%=baseURL%>/js/sorttable/sortabletable.js"></script>
<script type="text/javascript" src="<%=baseURL%>/js/selectdate1.js"></script>
<link href="<%=baseURL%>/css/main.css" rel="stylesheet" type="text/css">
<!--有錯誤信息和提示信息時層要顯示的位置-->
<style type="text/css">
<!--
?#errorDiv {
?position: absolute;
?left: 20%;
?top: 20%;
?width: 352px;
?height: 21px;
?background-color: #FFFFFF;
?}
-->
</style>

?

publlic.js?? 不要的代碼請去除

?


function next_focus(text)
{
?if(window.event.keyCode ==13)
?{
??window.event.keyCode=9;
?}
}


function mouseovertd (o)
{
?o.style.color='#ffffff';
?o.style.backgroundColor='#B3B3B3';

}
function mouseouttd (o)
{
?o.style.color='#000000';
?o.style.backgroundColor='';

}

?

function goPage(flag,currPage,formId,formAction,formTarget,formMethod,pageNumId)
{
? var formObj=document.all(formId)
? ?formObj.target=formTarget;
?formObj.method=formMethod;
?if(flag=='go')
?{
??var obj=document.all(pageNumId)
?? if(isNaN(obj.value))
??? ?{
???? ? alert(pageNum_fireeagle);
???????? obj.select();
????? ?? return;
??? ?}
??else
??{
???currPage=obj.value
??}
?}

?pageMethod="pageMethod="+flag+"&currentPage="+currPage;
?formAction=formAction+"&"+pageMethod;
?formObj.action=formAction;
??????? top.bottom.document.all("process").innerHTML="<img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'>";
?formObj.submit();
}
function submitForm(formId,submitbutton)
{
? editModel_fireeagle=false;
?submitbutton.disabled=true
? var objForm =document.all(formId);
?? if(Validator.Validate(objForm,2))
?? {
??? top.bottom.document.all("process").innerHTML="<img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'>";
??? objForm.submit();
?? }
?? else
?? {
??????? submitbutton.disabled=false
?? }
}
function delOnClick(url,target)
{

?? if(window.confirm("確定刪除!"))
?? {
????? top.bottom.document.all("process").innerHTML="<img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'>"
???? if(target=='parent')
???? {
???? parent.location.href=url
???? }else if(target=='self')
???? {
???? location.href=url
???? }
?? }
}
function submitFormQuery(formId,queryFlag)
{

? var objForm =document.all(formId);
? objForm.is_QUERY.value=queryFlag;
? top.bottom.document.all("process").innerHTML="<img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'>";
?? objForm.submit();

}


function buttomOnClick(url,target)
{
?? top.bottom.document.all("process").innerHTML="<img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'>"
if(target=='parent')
?? {
??? parent.location.href=url
?? }else if(target=='self')
?? {
????? location.href=url
?? }
}

function changeEditModel()
{
? editModel_fireeagle=true
}

function isClose()
{
if(editModel_fireeagle)
? {
??? top.bottom.document.all("process").innerHTML="<img name='pro' src='"+baseURL+"/images/public/prosessEnd.gif' border='0'>"
? return exitPro
? }
}

//只能輸入數(shù)字
//頁面使用:<input type=text name=test value="" onKeypress="JHshNumberText()">
function JHshNumberText()
{
? if ( !(((window.event.keyCode >= 48) && (window.event.keyCode <= 57))
? || (window.event.keyCode == 13) || (window.event.keyCode == 46)
? || (window.event.keyCode == 45)))
? {
??? window.event.keyCode = 0 ;
? }
}

document.onkeydown = openHelp
function openHelp()
{
?if(window.event.keyCode==113)
??????? {
????????? if(top.main.document.title.indexOf("HELP")>=0)
????????? {
??????????? showModalDialog(baseURL+"/frame/help/"+top.main.document.title);
????????? }
??????? }

??? if(window.event.keyCode==116)
??? {
????? event.keyCode=0;
????? event.returnValue=false;

??? }
}
function jtrim(sstr)?? //去掉左右空格
{
? var astr="";
? var dstr="";
? var flag=0;
? for (i=0;i<sstr.length;i++)
? {if ((sstr.charAt(i)!=' ')||(flag!=0))
? {dstr+=sstr.charAt(i);
? flag=1;
? }
? }
? flag=0;
? for (i=dstr.length-1;i>=0;i--)
? {if ((dstr.charAt(i)!=' ')||(flag!=0))
? {astr+=dstr.charAt(i);
? flag=1;
? }
? }
? dstr="";
? for (i=astr.length-1;i>=0;i--) dstr+=astr.charAt(i);
? return dstr;
}

function popup(page,w,h){ //在窗口中央彈出窗口
? var width=screen.width;
? var height=screen.height;
? var arg;
? l=(width-w)/2;
? t=(height-h)/2;
? if (width>w && height>h) arg="top="+t+",left="+l+",";
? win=window.open (page,"select", arg+"height="+h+", width="+w+",toolbar=no, menubar=no, scrollbars=auto, resizable=no, location=no, status=no");
? return win;
}

function popupProject(page,w,h){ //在窗口中央彈出窗口
? var width=screen.width;
? var height=screen.height;
? var arg;
? l=(width-w)/2;
? t=(height-h)/2;
? if (width>w && height>h) arg="top="+t+",left="+l+",";
? win=window.open (page,"select", arg+"height="+h+", width="+w+",toolbar=no, menubar=no, scrollbars=yes, resizable=tes, location=no, status=no");
? return win;
}

var LookProjectWin=null;
function lookProject(url)
{
?LookProjectWin= popupProject(url,750,450)
}
function exitWindow()
{
? if(LookProjectWin!=null)
? {
??? LookProjectWin.close();
? }
}

//flag? 文件標(biāo)示
//filePath? 文件路經(jīng)標(biāo)示
//fileUpLoadHiddenIDNewObject 文件隱藏控件名標(biāo)示
//fileTitle 文件標(biāo)題控件名標(biāo)示
function showFileChange(flag,filePath,fileUpLoadHiddenIDNewObject,fileTitle)
{
? var sorFileName=document.all(filePath+flag).value
? var pos=sorFileName.lastIndexOf("\\");
? var fuleName=sorFileName.substring(pos+1);
? document.all(fileUpLoadHiddenIDNewObject+flag).value=fuleName
? var dotPos=fuleName.lastIndexOf(".");
? var fuleNameDot=fuleName.substring(0,dotPos);
? if(document.all(fileTitle+flag).value=="")
??? document.all(fileTitle+flag).value=fuleNameDot
}

struts配置

?<form-beans>
??? <form-bean name="testForm" type="com.ytstm.TestForm"/>
? </form-beans>

?<action path="/testArr" type="com.ytstm.TestArr" name="testForm">
????? <forward name="test" path="/testArr.jsp" />
??? </action>

?

?

com.ytstm.TestForm

package com.ytstm;

import org.apache.struts.action.*;

public class TestForm extends ActionForm{
??? public TestForm() {
??? }


}

com.ytstm.TestArr

package com.ytstm;

import org.apache.struts.action.ActionForward;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import java.util.*;
import org.apache.struts.upload.*;
import java.io.*;
import com.ytstm.util.UpLoadUtil;

public class TestArr extends org.apache.struts.action.Action{
??? public TestArr() {
??? }

??? public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
?{
??????????? List returnArr=UpLoadUtil.upload(form,request,"testTable","F:/ytstm/YTSTMWeb/fileset/","fileUpLoadNumberRow","fileUpLoadHiddenIDNewObject","fileTitle");
??????????? if(returnArr!=null)
??????????? {
??????????????? for(int i=0;i<returnArr.size();i++)
??????????????? {
??????????????????? Map map=(Map)returnArr.get(i);
??????????????????? System.out.println("TABLENAME==="+map.get("TABLENAME"));
??????????????????? System.out.println("FILENAME==="+map.get("FILENAME"));
??????????????????? System.out.println("FILEPATH==="+map.get("FILEPATH"));
??????????????????? System.out.println("FILETYPE==="+map.get("FILETYPE"));
??????????????????? System.out.println("FORMERLYFILENAME==="+map.get("FORMERLYFILENAME"));
??????????????? }
??????????? }
??????????? return mapping.findForward("test");
??????? }
}

com.ytstm.util.UpLoadUtil

package com.ytstm.util;

import org.apache.struts.action.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;
import org.apache.struts.upload.*;

public class UpLoadUtil {
??? public UpLoadUtil() {
??? }
??? /**
???? *
???? * @param form ActionForm
???? * @param request HttpServletRequest
???? * @param tableName String???? 表名
???? * @param storePath String???? 路經(jīng)
???? * @param fileNumControl String? 表示附件個數(shù)的頁面控件名
???? * @param fileNumControl String? 表示附件隱藏的頁面控件名
???? * @return List
???? * @throws IOException
???? */
??? public static List upload(ActionForm form, HttpServletRequest request,String tableName,String storePath,String fileNumControl,String hiddenIDNewObject,String fileTitle) throws
??????????? IOException
??? {
???????? List retList = new ArrayList(); //存放附件的信息
???????? Hashtable files = form.getMultipartRequestHandler().getFileElements();
??????? String strnumberRowNew = request.getParameter(fileNumControl);
??????? int intnumberRowNew = 0;
??????? FormFile ff[] = null;
??????? ff = new FormFile[files.size()];
??????? Enumeration fileKey = files.keys();
??????? int i = 0;

??????? while (fileKey.hasMoreElements()) {
??????????? String ffname = (String) fileKey.nextElement();

??????????? ff[i] = (FormFile) files.get(ffname);
??????????? i++;
??????? }

??????? for (int a = 0; a < ff.length; a++) {
??????????? if (ff[a] == null || ff[a].getFileSize() == 0 ||
??????????????? ff[a].getFileName() == null
??????????????? || ff[a].getFileName().equals("")) {
??????????? } else {

?????????????? Map fileMap=new HashMap();
?????????????? fileMap.put("TABLENAME",tableName); //表名,設(shè)為信息表

??????????????? InputStream stream = ff[a].getInputStream();
??????????????? java.util.Date date = new java.util.Date(System.
??????????????????????? currentTimeMillis()); //獲取當(dāng)前時間
??????????????? String virFileName = date.getTime()+""+a;
??????????????? fileMap.put("FORMERLYFILENAME",ff[a].getFileName()); //標(biāo)題文件的名字


??????????????? if (strnumberRowNew != null) {
??????????????????? intnumberRowNew = Integer.parseInt(strnumberRowNew);
??????????????????? for (int n = 1; n<= intnumberRowNew; n++) {
??????????????????? String filesor = request.getParameter(hiddenIDNewObject + n);
??????????????????????? if (filesor!=null&&filesor.equals(ff[a].getFileName())) {
??????????????????????????? String fileTitleValue = request.getParameter(fileTitle + n);
??????????????????????????? fileMap.put("FILENAME",fileTitleValue);
??????????????????????????? break;
??????????????????????? }
??????????????????? }
??????????????? }


??????????????? int dotIndex = ff[a].getFileName().lastIndexOf(".");
??????????????? String fileType = ff[a].getFileName().substring(dotIndex + 1);
??????????????? fileMap.put("FILEPATH",virFileName + "." + fileType); //路徑
??????????????? fileMap.put("FILETYPE",fileType);


??????????????? retList.add(fileMap);

??????????????? OutputStream bos =
??????????????????????? new FileOutputStream(storePath + virFileName +
???????????????????????????????????????????? "." + fileType);

??????????????? int bytesRead = 0;
??????????????? byte[] buffer = new byte[8192];
??????????????? while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
??????????????????? bos.write(buffer, 0, bytesRead);
??????????????? }
??????????????? bos.close();
??????????? }
??????? }

???????? return retList;

??? }
??? /**
???? *
???? * @param request HttpServletRequest
???? * @param list List????????????????? 數(shù)據(jù)中以存在附件
???? * @param fileNumControl String????? 同上
???? * @param hiddenIDNewObject String?? 同上
???? * @param fileTitle String?????????? 同上
???? * @return List
???? */
??? public List combinateEditList(HttpServletRequest request, List list,String fileNumControl,String hiddenIDNewObject,String fileTitle) {
????????? List result=new ArrayList();
????????? if(list==null||list.size()==0) return new ArrayList();
?????????? String strnumberRowNew = request.getParameter(fileNumControl);
????????? int? intnumberRowNew=0;
?????????? if (strnumberRowNew != null) {
?????????????? intnumberRowNew = Integer.parseInt(strnumberRowNew);
?????????????? for (int n = 1; n <= intnumberRowNew; n++) {
?????????????????? String filesor = request.getParameter("hiddenIDNewObject" +? n);
?????????????????? String fileTitleValue = request.getParameter(fileTitle + n);
?????????????????? for(int i=0;i<list.size();i++)
?????????????????? {
?????????????????????? Map fileMap = (Map)list.get(i);
?????????????????????? if((fileMap.get("ACCESSORYID").toString()).equals(filesor))
?????????????????????? {
?????????????????????????? fileMap.put("FILENAME",fileTitleValue);
?????????????????????????? result.add(fileMap);
??????????????????????????? break;
?????????????????????? }
?????????????????? }
?????????????? }
?????????? }
?????????? return result;
??? }

}

如果出現(xiàn)中文亂碼,請修改struts源程序的相關(guān)類把編碼修改成utf-8,網(wǎng)上可以查到。



???MengChuChen 2007-02-02 20:34 發(fā)表評論
]]>
Struts Validator驗證器使用指南 http://www.aygfsteel.com/19851985lili/articles/97634.html???MengChuChen???MengChuChenFri, 02 Feb 2007 12:21:00 GMThttp://www.aygfsteel.com/19851985lili/articles/97634.htmlhttp://www.aygfsteel.com/19851985lili/comments/97634.htmlhttp://www.aygfsteel.com/19851985lili/articles/97634.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/97634.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/97634.html閱讀全文

???MengChuChen 2007-02-02 20:21 發(fā)表評論
]]>
StrutsTest使用手冊 http://www.aygfsteel.com/19851985lili/articles/93525.html???MengChuChen???MengChuChenFri, 12 Jan 2007 12:10:00 GMThttp://www.aygfsteel.com/19851985lili/articles/93525.htmlhttp://www.aygfsteel.com/19851985lili/comments/93525.htmlhttp://www.aygfsteel.com/19851985lili/articles/93525.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/93525.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/93525.html閱讀全文

???MengChuChen 2007-01-12 20:10 發(fā)表評論
]]>
Jakarta-Common-BeanUtils使用筆記http://www.aygfsteel.com/19851985lili/articles/93513.html???MengChuChen???MengChuChenFri, 12 Jan 2007 11:13:00 GMThttp://www.aygfsteel.com/19851985lili/articles/93513.htmlhttp://www.aygfsteel.com/19851985lili/comments/93513.htmlhttp://www.aygfsteel.com/19851985lili/articles/93513.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/93513.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/93513.html第一次接觸BeanUtils是在學(xué)習(xí)Struts的過程中,在Struts中它被大量用于處理FormBean

BeanUtils主要提供了對于JavaBean進行各種操作,

?????? BeanUtils一共分4個包:

????????? org.apache.commons.beanutils

????????? org.apache.commons.beanutils.converters

????????? org.apache.commons.beanutils.locale

????????? org.apache.commons.beanutils.locale.converters

其中上面兩個是BeanUtils的默認(rèn)實現(xiàn),它沒有針對本地化的任何處理,這個可以提高執(zhí)行效率。但是若你的程序?qū)τ诒镜鼗幸蟮脑挘沁€是使用下面2個包比較安全。

?

2.?? org.apache.commons.beanutils

?????? 這個包主要提供用于操作JavaBean的工具類,Jakarta-Common-BeanUtils的主要功能都在這個包里實現(xiàn)。

??? 下面分別介紹幾個主要的工具類:

2.1.BeanUtil

1、首先,我先定義一個JavaBean作為之后例子的操作對象。

????public class Company

????{

? ????private String name;

? ????private HashMap address = new HashMap();

? ????private String[] otherInfo;

? ????private ArrayList product;

? ????private ArrayList employee;

? ????private HashMap telephone;

?

? ????public Company(){}

?

????? public String getName()

? ????{

??? ????return name;

? ????}

? ????public void setName(String name)

? ????{

??? ????this.name = name;

? ????}

?

? ????public String getAddress(String type)

? ????{

??????? return address.get(type).toString();

? ????}

? ????public void setAddress(String type, String address)

? ????{

??? ????this.address.put(type,address);

? ????}

?

? ????public String[] getOtherInfo()

? ????{

??? ????return otherInfo;

? ????}

? ????public void setOtherInfo(String[] otherInfo)

? ????{

??? ????this.otherInfo = otherInfo;

????? }

?

? ????public ArrayList getProduct()

? ????{

??? ????return product;

? ????}

? ????public void setProduct(ArrayList product)

? ????{

??? ????this.product = product;

????? }

?

? ????public ArrayList getEmployee()

? ????{

??? ????return employee;

? ????}

????? public void setEmployee(ArrayList employee)

? ????{

??? ????this.employee = employee;

? ????}

?

? ????public HashMap getTelephone()

? ????{

??? ????return telephone;

? ????}

? ????public void setTelephone(HashMap telephone)

? ????{

??? ????this.telephone = telephone;

? ????}

????}

2BeanUtils可以直接getset一個屬性的值。它將property分成3種類型:

?????? Simple——簡單類型,如StirngInt……

?????? Indexed——索引類型,如數(shù)組、arrayList……

?????? Maped——這個不用說也該知道,就是指Map啦,比如HashMap……

?????? 訪問不同類型的數(shù)據(jù)可以直接調(diào)用函數(shù)getPropertysetProperty。它們都只有2個參數(shù),第一個是JavaBean對象,第二個是要操作的屬性名。

Company c = new Company();

c.setName("Simple");

?

對于Simple類型,參數(shù)二直接是屬性名即可

//Simple

??? System.out.println(BeanUtils.getProperty(c, "name"));

??? 對于Map類型,則需要以“屬性名(key值)”的形式

//Map

??? System.out.println(BeanUtils.getProperty(c, "address (A2)"));

??? HashMap am = new HashMap();

??? am.put("1","234-222-1222211");

??? am.put("2","021-086-1232323");

??? BeanUtils.setProperty(c,"telephone",am);

??? System.out.println(BeanUtils.getProperty(c, "telephone (2)"));

??? 對于Indexed,則為“屬性名[索引值]”,注意這里對于ArrayList和數(shù)組都可以用一樣的方式進行操作。

//index

??? System.out.println(BeanUtils.getProperty(c, "otherInfo[2]"));

??? BeanUtils.setProperty(c, "product[1]", "NOTES SERVER");

??? System.out.println(BeanUtils.getProperty(c, "product[1]"));

?

?????? 當(dāng)然這3種類也可以組合使用啦!

??? //nest

??? System.out.println(BeanUtils.getProperty(c, "employee[1].name"));

?

3、此外,還有一個很重要的方法copyProperty,可以直接進行Bean之間的clone

?????? Company c2 = new Company();

??? ????BeanUtils.copyProperties(c2, c);

?? ????但是這種copy都是淺拷貝,復(fù)制后的2Bean的同一個屬性可能擁有同一個對象的ref,這個在使用時要小心,特別是對于屬性為自定義類的情況。

4、最后還有populate,它用于將一個map的值填充到一個bean中,其函數(shù)原型如下:

public void populate(java.lang.Object?bean,

??????????????? java.util.Map?properties)

????????????? throws java.lang.IllegalAccessException,

???????????????????? java.lang.reflect.InvocationTargetException

struts中這個函數(shù)被用于從http request中取得參數(shù)添加到FormBean,目前好像我也沒有看到這個函數(shù)還有什么其他的用途?!以后想到再說吧:P

?

2.2.LazyDynaBean

?????? 它實現(xiàn)一個動態(tài)的Bean,可以直接往里面加入屬性,作為一個JavaBean一樣使用,也可以用上面的BeanUtilsget/set方法進行操作,而不用事先定義一個標(biāo)準(zhǔn)的JavaBean類啦:)

記得在J2ee設(shè)計模式中有一種Value Object的模式,用于在MVC各層之間傳遞數(shù)據(jù),避免直接傳遞大業(yè)務(wù)對象引起的性能問題,為了避免在項目中出現(xiàn)很多Bean類,在書中提供了一個動態(tài)Value Object的實現(xiàn)(通過擴展Map)。這里LazyDynaBean則可以作為一種更加成熟、穩(wěn)定的實現(xiàn)來使用。呵呵,原來曾打算自己寫一個類似的value object類的,現(xiàn)在看來可以直接用這個啦:P

?????? 言歸正傳,LazyBean的確提供了一個很不錯的DynaBean的實現(xiàn)。而且就像它的名字中表述的那樣,它的確是為我這樣的懶人考慮的很周到,用起來幾乎不需要寫什么多余的代碼^_^,下面就看看使用的例子吧!

?????? ? //這里使用LazyDynaMap,它是LazyBean的一個輕量級實現(xiàn)

????? LazyDynaMap dynaBean1 = new LazyDynaMap();

?

????? dynaBean1.set("foo", "bar");????????????????? // simple

????? dynaBean1.set("customer", "title", "Mr");???? ???// mapped

????? dynaBean1.set("address", 0, "address1");????? ???// indexed

????? System.out.println(dynaBean1.get("address",0));

?

????? Map myMap = dynaBean1.getMap();?????????? // retrieve the Map

????? System.out.println(myMap.toString());

?????? 上面的例子可以看到,它可以在set時自動增加beanproperty(既賦值的同時增加Bean中的property),同時也支持3中類型的property,并且LazyDynaMap還可以導(dǎo)出為map

?????? 對于這個類還有兩個重要的Field要注意:

?????? returnnull——指定在get方法使用了一個沒有定義過的property時,DynaBean的行為。

?????? ? //取的字段的信息

????? dynaBean1.setReturnNull(true);//設(shè)為ture。若Bean中沒有此字段,返回null

??? ????????????????????????????//默認(rèn)為false。若Bean中沒有此字段,自動增加一個:)

????? System.out.println(dynaBean1.get("aaa"));//此時返回null

?????? Restricted——指定是否允許改變這個beanproperty

//MutableDynaClass.setRestricted設(shè)為true后,字段不可再增刪和修改.

????? //默認(rèn)為false,允許增刪和修改

????? dynaBean1.setRestricted(true);

????? dynaBean1.set("test","error");//這里會出錯!

?????? 通過設(shè)置這兩個屬性,可以防止意外修改DynaBeanproperty。在設(shè)計架構(gòu)時,你可以在后臺從數(shù)據(jù)表或xml文件自動產(chǎn)生DynaBean,在傳到控制層和表示層之前設(shè)置上述屬性使其Bean結(jié)構(gòu)不允許修改,如此就不可能無意中修改Bean包含的屬性……這樣既可以享用它的便利,有可以防止由此引入的錯誤可能,設(shè)計者實在深得偷懶的精髓啊!!!!!

?

3.?? 其他

3.1.BeanUtilsPropertyUtils

?????? 這兩個類幾乎有一摸一樣的功能,唯一的區(qū)別是:BeanUtils在對Bean賦值是會進行類型轉(zhuǎn)化。舉例來說也就是在copyProperty時只要屬性名相同,就算類型不同,BeanUtils也可以進行copy;而PropertyBean則可能會報錯!!

?????? 針對上面的例子,新建一個Company2的類,其中代碼與Company一樣,只是將otherinfoString[]改為String

????? Company c = init();

????? Company2 c2 = new Company2();

?????

????? BeanUtils.copyProperties(c2,c);

//????? PropertyUtils.copyProperties(c2,c); 這句會報錯!!

????? System.out.println(c2.getOtherInfo());

??? 當(dāng)然2Bean之間的同名屬性的類型必須是可以轉(zhuǎn)化的,否則用BeanUtils一樣會報錯。

?????? 若實現(xiàn)了org.apache.commons.beanutils.Converter接口則可以自定義類型之間的轉(zhuǎn)化。

由于不做類型轉(zhuǎn)化,用PropertyUtils在速度上會有很大提高!

此外,不作類型轉(zhuǎn)化還有一個好處,如下面的代碼:

????? //test data type convert

//????? ArrayList a1 = BeanUtils.getProperty(c,"product"); //BeanUtils返回的是String

????? System.out.println("--" + BeanUtils.getProperty(c,"product")); ????//取出后直接被轉(zhuǎn)為String

????? ArrayList a = (ArrayList)PropertyUtils.getProperty(c,"product");//PropertyUtils返回的是Object

????? System.out.println("--" + a.get(1));

BeanUtils無法返回一個對象(除非自己寫一個Converter),它會自動進行類型轉(zhuǎn)化,然后返回String。對于想返回java類或自定義類的話,還是不要老它大駕轉(zhuǎn)化了。

?

3.2.Utils

?????? 所有的XXXUtils類都提供的是靜態(tài)方法,可以直接調(diào)用,其主要實現(xiàn)都在相應(yīng)的XXXUtilsBean中:

BeanUtils? ?? ——> BeanUtilsBean

?????? ConvertUtils? ——> ConvertUtilsBean

??? PropertyUtils ——> PropertyUtilsBean

?

其意思看類名也應(yīng)該知道的差不多了,我就不再廢話啦!當(dāng)然你也可以直接調(diào)用那些XXXUtilsBean,功能都一樣!



???MengChuChen 2007-01-12 19:13 發(fā)表評論
]]>
主站蜘蛛池模板: 台东县| 抚宁县| 福州市| 两当县| 盘山县| 明星| 潮州市| 察雅县| 和林格尔县| 边坝县| 宜兰市| 邯郸县| 宁武县| 丰县| 东丰县| 桦南县| 固镇县| 景东| 吴旗县| 田林县| 嘉禾县| 敦化市| 新和县| 化州市| 柳河县| 同心县| 扶沟县| 隆尧县| 桐梓县| 大连市| 凤凰县| 天津市| 商城县| 四子王旗| 长宁县| 大兴区| 林西县| 鄂托克旗| 临安市| 正阳县| 新余市|