<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java Study Center  
    日歷
    <2008年9月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011
    統(tǒng)計
    • 隨筆 - 40
    • 文章 - 3
    • 評論 - 0
    • 引用 - 0

    導航

    常用鏈接

    留言簿(1)

    隨筆檔案(40)

    文章檔案(3)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

     

    在我已往的Struts 1.x項目經(jīng)驗中,有個問題不時的出現(xiàn)——在創(chuàng)建FormBean時,對于某個屬性到底應(yīng)該用String還是其它類型?

    開發(fā)Web應(yīng)用程序與開發(fā)傳統(tǒng)桌面應(yīng)用程序不同,Web應(yīng)用程序?qū)嶋H上是分布個不同的主機(當然也可以同一個主機,不過比較少見)上的兩個進程之間互交。這種互交建立在HTTP之上,它們互相傳遞是都是字符串。換句話說, 服務(wù)器可以的接收到的來自用戶的數(shù)據(jù)只能是字符串或字符數(shù)組,而在服務(wù)器上的對象中,這些數(shù)據(jù)往往有多種不同的類型,如日期(Date),整數(shù)(int),浮點數(shù)(float)或自定義類型(UDT)等,如圖1所示。因此,我們需要服務(wù)器端將字符串轉(zhuǎn)換為適合的類型。

    圖1 UI與服務(wù)器對象關(guān)系
    圖1 UI與服務(wù)器對象關(guān)系

    同樣的問題也發(fā)生在使用UI展示服務(wù)器數(shù)據(jù)的情況。HTML的Form控件不同于桌面應(yīng)用程序可以表示對象,其值只能為字符串類型,所以我們需要通過某種方式將特定對象轉(zhuǎn)換成字符串。

    要實現(xiàn)上述轉(zhuǎn)換,Struts 2.0中有位魔術(shù)師可以幫到你——Converter。有了它,你不用一遍又一遍的重復編寫諸如此類代碼:

    Date birthday = DateFormat.getInstance(DateFormat.SHORT).parse(strDate);
    <input type="text" value="<%= DateFormat.getInstance(DateFormat.SHORT).format(birthday) %>" />

    好了,現(xiàn)在讓我們來看一個例子。

    轉(zhuǎn)換器——Hello World

    在我的上一篇文章《在Struts 2.0中國際化(i18n)您的應(yīng)用程序》的最后我舉了一個可以讓用戶方便地切換語言的例子,下面例子與其相似,但實現(xiàn)方法不同。

    首先,如《在Struts 2.0中國際化(i18n)您的應(yīng)用程序》的第一個例子一樣,創(chuàng)建和配置默認的資源文件;

    接著,新建源代碼文件夾下的tutorial包創(chuàng)建HelloWorld.java文件,代碼如下:

    package tutorial;

    import java.util.Locale;

    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.util.LocalizedTextUtil;

    public class HelloWorld extends ActionSupport {
       
    private String msg;
       
    private Locale loc = Locale.US;
      
       
    public String getMsg() {
           
    return msg;        
       }

       
       
    public Locale getLoc() {
           
    return loc;
       }

       
       
    public void setLoc(Locale loc) {
           
    this .loc = loc;
       }

       
       @Override
       
    public String execute() {
           
    // LocalizedTextUtil是Struts 2.0中國際化的工具類,<s:text>標志就是通過調(diào)用它實現(xiàn)國際化的
           msg = LocalizedTextUtil.findDefaultText( " HelloWorld " , loc);
           
    return SUCCESS;
       }

    }

    然后,在源代碼文件夾下的struts.xml加入如下代碼新建Action:

    < package name ="ConverterDemo" extends ="struts-default" >
       
    < action name ="HelloWorld" class ="tutorial.HelloWorld" >
           
    < result > /HelloWorld.jsp </ result >
       
    </ action >
    </ package >

    再在Web文件夾下,新建 HelloWorld.jsp,代碼如下:

    < %@ page   contentType ="text/html; charset=UTF-8" % >
    < %@taglib prefix ="s" uri ="/struts-tags" % >
    < html >
    < head >
       
    < title > Hello World </ title >
    </ head >
    < body >
       
    < s:form action ="HelloWorld" theme ="simple" >            
            Locale:
    < s:textfield name ="loc" /> &nbsp; < s:submit />
       
    </ s:form >    
       
    < h2 >< s:property value ="msg" /></ h2 >
    </ body >
    </ html >

    接下來,在源代碼文件夾的tutorial包中新建LocaleConverter.java文件,代碼如下:

    package tutorial;

    import java.util.Locale;
    import java.util.Map;

    public class LocaleConverter extends ognl.DefaultTypeConverter {
       @Override
       
    public Object convertValue(Map context, Object value, Class toType) {
           
    if (toType == Locale. class ) {
               String locale
    = ((String[]) value)[ 0 ];
               
    return new Locale(locale.substring( 0 , 2 ), locale.substring( 3 ));
           }
    else if (toType == String. class ) {
               Locale locale
    = (Locale) value;
               
    return locale.toString();
           }

           
    return null ;
       }

    }

    再接下來,在源代碼文件夾下新建xwork-conversion.properties,并在其中添加如下代碼:

    java.util.Locale = tutorial.LocaleConverter

    發(fā)布運行應(yīng)用程序,在瀏覽器中鍵入http://localhost:8080/Struts2_Converter/HelloWorld.action,輸出頁面如圖2所示:
    圖2 HelloWorld英文輸出
    圖2 HelloWorld英文輸出

    在Locale輸入框中輸入“zh_CN”,按“Submit”提交,出現(xiàn)如圖3所示頁面:
    圖3 HelloWorld中文輸出
    圖3 HelloWorld中文輸出

    上述例子中,Locale文本輸入框?qū)?yīng)是Action中的類型為java.util.Locale的屬性loc,所以需要創(chuàng)建一個自定義轉(zhuǎn)變器實現(xiàn)兩者間的轉(zhuǎn)換。所有的Struts 2.0中的轉(zhuǎn)換器都必須實現(xiàn)ognl.TypeConverter接口。 為了簡單起見,OGNL包也為你提供了ognl.DefaultTypeConverter類去幫助您實現(xiàn)轉(zhuǎn)換器。在例子中,LocaleConverter繼承了ognl.DefaultTypeConverter,重載了其方法原型為“public Object convertValue(Map context, Object value, Class toType)”的方法。下面簡單地介紹一下函數(shù)的參數(shù):

    1. context——用于獲取當前的ActionContext
    2. value——需要轉(zhuǎn)換的值
    3. toType——需要轉(zhuǎn)換成的目標類型
    實現(xiàn)轉(zhuǎn)換器,我們需要通過配置告訴Struts 2.0。我們可以通過以下兩種方法做到這點:
    1. 配置全局的類型轉(zhuǎn)換器,也即是上例的做法——在源代碼文件夾下,新建一個名為“xwork-conversion.properties”的配置文件,并在文件中加入“待轉(zhuǎn)換的類型的全名(包括包路徑和類名)=轉(zhuǎn)換器類的全名”對;
    2. 應(yīng)用于某個特定類的類型轉(zhuǎn)換器,做法為在該類的包中添加一個格式為“類名-conversion.properties”的配置文件,并在文件中加入“待轉(zhuǎn)換的屬性的名字=轉(zhuǎn)換器類的全名”對。上面的例子也可以這樣配置——在源代碼文件夾的tutorial包下新建名為“HelloWorld-conversion.properties”文件,并在其中加入“loc=tutorial.LocaleConverter”。
    在繼承DefaultTypeConverter時,如果是要將value轉(zhuǎn)換成其它非字符串類型時,要記住value是String[]類型,而不是String類型。它是通過request.getParameterValues(String arg)來獲得的,所以不要試圖將其強行轉(zhuǎn)換為String類型。

    已有的轉(zhuǎn)換器

    對于一此經(jīng)常用到的轉(zhuǎn)換器,如日期、整數(shù)或浮點數(shù)等類型,Struts 2.0已經(jīng)為您實現(xiàn)了。下面列出已經(jīng)實現(xiàn)的轉(zhuǎn)換器。

    1. 預(yù)定義類型,例如int、boolean、double等;
    2. 日期類型, 使用當前區(qū)域(Locale)的短格式轉(zhuǎn)換,即DateFormat.getInstance(DateFormat.SHORT);
    3. 集合(Collection)類型, 將request.getParameterValues(String arg)返回的字符串數(shù)據(jù)與java.util.Collection轉(zhuǎn)換;
    4. 集合(Set)類型, 與List的轉(zhuǎn)換相似,去掉相同的值;
    5. 數(shù)組(Array)類型, 將字符串數(shù)組的每一個元素轉(zhuǎn)換成特定的類型,并組成一個數(shù)組。
    對于已有的轉(zhuǎn)換器,大家不必再去重新發(fā)明輪子。Struts在遇到這些類型時,會自動去調(diào)用相應(yīng)的轉(zhuǎn)換器。

    批量封裝對象(Bean)

    不知道大家是否遇過這種情況,在一個頁面里同時提交幾個對象。例如,在發(fā)布產(chǎn)品的頁面,同時發(fā)布幾個產(chǎn)品。我在之前一個項目就遇到過這種需求,當時用的是Struts 1.x。那是一個痛苦的經(jīng)歷,我在Google搜了很久都沒有理想的結(jié)果。幸運的是,在Struts 2.0中這種痛苦將一去不復返。下面我就演示一下如何實現(xiàn)這個需求。

    首先,在源代碼文件夾下的tutorial包中新建Product.java文件,內(nèi)容如下:

    package tutorial;

    import java.util.Date;

    publicclass Product {
       
    private String name;
       
    privatedouble price;
       
    private Date dateOfProduction;
       
       
    public Date getDateOfProduction() {
           
    return dateOfProduction;
       }

       
       
    publicvoid setDateOfProduction(Date dateOfProduction) {
           
    this.dateOfProduction = dateOfProduction;
       }

       
       
    public String getName() {
           
    return name;
       }

       
       
    publicvoid setName(String name) {
           
    this.name = name;
       }

       
       
    publicdouble getPrice() {
           
    return price;
       }

       
       
    publicvoid setPrice(double price) {
           
    this.price = price;
       }
       
    }

    然后,在同上的包下添加ProductConfirm.java類,代碼如下:

    package tutorial;

    import java.util.List;

    import com.opensymphony.xwork2.ActionSupport;

    publicclass ProductConfirm extends ActionSupport {
       
    public List<Product> products;

       
    public List<Product> getProducts() {
           
    return products;
       }


       
    publicvoid setProducts(List<Product> products) {
           
    this.products = products;
       }

       
       @Override
       
    public String execute() {
           
    for(Product p : products) {
               System.out.println(p.getName()
    + " | "+ p.getPrice() +" | " + p.getDateOfProduction());
           }

           
    return SUCCESS;
       }

    }

    接看,在同上的包中加入ProductConfirm-conversion.properties,代碼如下:

    Element_products=tutorial.Product

    再在struts.xml文件中配置ProductConfirm Action,代碼片段如下:

    <action name="ProductConfirm" class="tutorial.ProductConfirm">
       
    <result>/ShowProducts.jsp</result>
    </action>

    在WEB文件夾下新建AddProducts.jsp,內(nèi)容如下:

    <%@ page  contentType="text/html; charset=UTF-8"%>
    <%@taglib prefix="s" uri="/struts-tags"%>
    <html>
    <head>
       
    <title>Hello World</title>
    </head>
    <body>
       
    <s:form action="ProductConfirm" theme="simple">            
           
    <table>
               
    <tr style="background-color:powderblue; font-weight:bold;">
                   
    <td>Product Name</td>
                   
    <td>Price</td>
                   
    <td>Date of production</td>
               
    </tr>
               
    <s:iterator value="new int[3]" status="stat">
                   
    <tr>
                       
    <td><s:textfield name="%{'products['+#stat.index+'].name'}"/></td>
                       
    <td><s:textfield name="%{'products['+#stat.index+'].price'}"/></td>
                       
    <td><s:textfield name="%{'products['+#stat.index+'].dateOfProduction'}"/></td>
                   
    </tr>
               
    </s:iterator>
               
    <tr>
                   
    <td colspan="3"><s:submit /></td>
               
    </tr>
           
    </table>
       
    </s:form>    
    </body>
    </html>

    在同樣的文件夾下創(chuàng)建ShowProducts.jsp,內(nèi)容如下:

    <%@ page  contentType="text/html; charset=UTF-8"%>
    <%@taglib prefix="s" uri="/struts-tags"%>
    <html>
    <head>
       
    <title>Hello World</title>
    </head>
    <body>    
       
    <table>
           
    <tr style="background-color:powderblue; font-weight:bold;">
               
    <td>Product Name</td>
               
    <td>Price</td>
               
    <td>Date of production</td>
           
    </tr>
           
    <s:iterator value="products" status="stat">
               
    <tr>
                   
    <td><s:property value="name"/></td>
                   
    <td>$<s:property value="price"/></td>
                   
    <td><s:property value="dateOfProduction"/></td>
               
    </tr>
           
    </s:iterator>
       
    </table>
    </body>
    </html>

    發(fā)布運行應(yīng)用程序,在瀏覽器中鍵入http://localhost:8080/Struts2_Converter/AddProducts.jsp,出現(xiàn)如圖4所示頁面:
    圖4 添加產(chǎn)品頁面
    圖4 添加產(chǎn)品頁面

    按圖4所示,填寫表單,按“Submit”提交,出現(xiàn)圖5所示頁面:
    圖5 查看產(chǎn)品頁面
    圖5 查看產(chǎn)品頁面

    查看服務(wù)器的控制臺,有如下輸出:

    Expert One-on-One J2EE Development without EJB | 39.99 | Mon Jun 2100:00:00 CST 2004
    Pro Spring |
    32.99 | Mon Jan 3100:00:00 CST 2005
    Core J2EE Patterns: Best Practices and Design Strategies
    , Second Edition | 34.64 | Sat May 1000:00:00 CST 2003

    上面的代碼并不復雜,但有幾點需要說明:

    1. ProductConfirm文件中的for(Product p : productes)的寫法是J2SE 5.0中的新特性,作用遍歷products列表;
    2. List<Product>也是J2SE 5.0的才有的泛型(Generic);
    3. ProductConfirm-conversion.properties中“Element_products=tutorial.Product”是告訴Struts 2.0列表products的元素的類型為Product,而不是定義轉(zhuǎn)換器;
    4. 在AddProducts.jsp的<s:textfield>的name為“%{'products['+#stat.index+'].name'}”,%{exp}格式表示使用OGNL表達式,上述表達式的相當于<%= "products[" + stat.index + "].name" %>,至于<s:iterator>標志的用法可以參考我之前的文章《常用的Struts 2.0的標志(Tag)介紹》。

    轉(zhuǎn)換錯誤處理

    不知道大家在運行上面的例子時,有沒有填錯日期或數(shù)字情況,又或者您有沒有思考過這種情況?如果還沒有嘗試的朋友可以試一下,在第一行的Price和Date of production中輸入英文字母,然后按“Submit”提交。你會看到頁面為空白,再看一下服務(wù)器的控制臺輸出,有如下語句: 警告: No result defined for action tutorial.ProductConfirm and result input,它提示我們沒有為Action定義輸入結(jié)果,所以,我們應(yīng)該在源代碼文件夾下的struts.xml中的ProductConfirm Action中加入以下代碼:

    <result name="input">/AddProducts.jsp</result>

    重新加載應(yīng)用程序,刷新瀏覽器重新提交請求,這時頁面返回AddProducts.jsp,格式錯誤的輸入框的值被保留,如下圖6所示:
    圖6 沒有提示的錯返回頁面
    圖6 沒有提示的錯返回頁面

    當然,我們還可以在頁面上加上錯誤提示信息,通過在AddProducts.jsp的“<body>”后,加入下面代碼可以實現(xiàn):

    <div style="color:red">
       
    <s:fielderror />
    </div>

    刷新瀏覽器,重新提交請求,出現(xiàn)如圖7所示頁面:
    圖7 帶提示的錯返回頁面
    圖7 帶提示的錯返回頁面

    以上的功能的都是通過Struts 2.0里的一個名為conversionError的攔截器(interceptor)工作,它被注冊到默認攔截器棧(default interceptor stack)中。Struts 2.0在轉(zhuǎn)換出錯后,會將錯誤放到ActionContext中,在conversionError的作用是將這些錯誤封裝為對應(yīng)的項錯誤(field error),因此我們可以通過<s:fielderror />來將其在頁面上顯示出來。另外,大家看第二和第三行的Price都被賦為0.0的值,而第一行則保留其錯誤值。這同樣是conversionError的功勞——沒有出錯的行調(diào)用的products[index].price(默認值為0.0),而出錯的行則會被賦為頁面所提交的錯誤值,這樣可以提供更好的用戶體驗。

    總結(jié)

    Struts 2.0的轉(zhuǎn)換器簡化的WEB應(yīng)用程序的模型,為我們的編程帶來極大的方便。

    posted on 2008-09-17 15:32 綠茶_鄭州 閱讀(100) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
     
    Copyright © 綠茶_鄭州 Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 18以下岁毛片在免费播放| 亚洲综合精品香蕉久久网| 在线观看亚洲精品福利片| 国产特黄一级一片免费| 四虎永久在线精品视频免费观看| 亚洲成a人片在线网站| 在线观看免费无码专区| 不卡精品国产_亚洲人成在线| 国产亚洲一卡2卡3卡4卡新区 | 亚洲国产成a人v在线观看| 91精品免费不卡在线观看| 亚洲va中文字幕无码久久不卡| 久久er国产精品免费观看8| 亚洲色图在线播放| 最近2019年免费中文字幕高清| 亚洲欧美日韩综合久久久| 日本免费一二区在线电影| 亚洲欧美第一成人网站7777 | 亚洲色婷婷一区二区三区| 五月天国产成人AV免费观看| 国产亚洲精品免费视频播放| 久草视频在线免费| 亚洲中文字幕无码中文字| 日本v片免费一区二区三区| 九九精品成人免费国产片| 亚洲精品一区二区三区四区乱码| 91在线视频免费播放| 日韩国产精品亚洲а∨天堂免| 亚洲国产日韩在线观频| 中文字幕在线免费看线人| 中文字幕在线观看亚洲| 毛片免费观看的视频在线| 国产亚洲漂亮白嫩美女在线 | 中文字幕日韩亚洲| 成人免费毛片视频| 99re在线这里只有精品免费| 国产精品高清视亚洲精品| 亚洲国产精品嫩草影院在线观看 | 韩国免费三片在线视频| 精品人妻系列无码人妻免费视频| 亚洲综合色一区二区三区|