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

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

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

    城市獵人

    在一網情深的日子里,誰能說得清是苦是甜,只知道確定了就義無反顧
    posts - 1, comments - 7, trackbacks - 0, articles - 89

    我們在應用 DWR 調用遠程方法時涉及到 JS 與 JAVA 之間參數和返回值的數據轉換,例如:

    JS 的 123 與 Java 的 int  或 Integer、long 間的轉換
    JS 的 "2009-06-23" 與 Java 的 java.util.Date 之間的轉換
    JS 的 "[1,2,3]" 與 Java 的 int[] 間的轉換
    JS 的 "{id:123, name: 'Unmi'}" 與 Java 的 Class Person{int id; String name} 間的轉換

    或者更復雜的嵌套類型( "{id:123, name: 'Unmi', blogs:['http://unmi.blogjava.net','http://blog.csdn.net/kypfos']}" ) 與 Java 類型間的轉換,等等。那么這一切是怎么進行的呢?其實我們見識過很多組件的類型映射,如 Java 的 PropertyEditor、Hibernate(UserType)、iBatis(TypeHandler) 的類型映射,Struts1/2 中 Form/Model 用的 Converter 等。

    這里我來稍稍分析 DWR 的 Converter 實現,以及說明如何定制自己的 Converter。本文所用 DWR 是 2.0.5 版。

    1. DWR 內置的 Converter 及應用類型

    名稱 應用類型 轉換器
    null void,java.lang.Void NullConverter
    enum   EnumConverter
    primitive boolean,byte,short,int,long,float,double,char,
    java.lang.Boolean,java.lang.Byte,java.lang.Short,
    java.lang.Integer,java.lang.Long,java.lang.Float,
    java.lang.Double,java.lang.Character
    PrimitiveConverter
    bignumber java.math.BigInteger,java.math.BigDecimal BigNumberConverter
    string java.lang.String StringConverter
    array [Z,[B,[S,[I,[J,[F,[D,[C,[L* ArrayConverter
    map java.util.Map MapConverter
    collection java.util.Collection CollectionConverter
    date java.util.Date,java.sql.Date,java.sql.Time,
    java.sql.Timestamp,java.util.Calendar
    DateConverter
    dom org.w3c.dom.Node,org.w3c.dom.Element,org.w3c.dom.Document DOMConverter
    dom4j org.dom4j.Document,org.dom4j.Element,org.dom4j.Node DOM4JConverter
    jdom org.jdom.Document,org.jdom.Element JDOMConverter
    xom nu.xom.Document,nu.xom.Element,nu.xom.Node XOMConverter
    servlet javax.servlet.ServletConfig,javax.servlet.ServletContext,
    javax.servlet.http.HttpServletRequest,
    javax.servlet.http.HttpServletResponse,
    javax.servlet.http.HttpSession
    ServletConverter
    bean   BeanConverter
    object   ObjectConverter
    hibernate2   H2BeanConverter
    hibernate3   H3BeanConverter
    url java.net.URL URLConverter
    exception   ExceptionConverter
    miniException java.lang.Throwable MinimalistExceptionConverter


    它們是應用啟動的時候,通過 org.directwebremoting.servlet.DwrServlet 初始化 dwr-2.0.5.jar!/org/directwebremoting/dwr.xml 文件加載進來的。例如:

    <converter id="date" class="org.directwebremoting.convert.DateConverter"/> 注冊了 date 轉換器
    <convert converter="date" match="java.util.Date"/> 應用注冊的 date 轉換器應用到 java.util.Date 類型

    看到上面,你也許會驚訝一下,我們平時可能也就用下 bean 轉換器,其他用內置就行。然而 DWR 確為我們考慮的很周到的,包括 hibernate 相關的,URL、Servlet、Dom 等相關類型的轉換器。

    2. DWR 如何確定用哪個 Converter?

    DWR 是根據方法參數來確定入口參數的 Converter、根據返回值類型確定傳向 JS 的出口參數的 Converter。總之是以 Java 方法原型為基準來決定每一參數或返回值各自用哪個 Converter 來轉換數據。

    在 BaseCallMarshaller.marshallInbound(HttpServletRequest request, HttpServletResponse response) 方法中,使用

    Class paramType = method.getParameterTypes()[j] 來獲得參數的類型,然后從已加載的 Converter Map 中找到 Converter 名稱,進而確定 Converter 類名。

    而確定返回值類型就不是直接用反射的 method.getReturnType()。而是以反射方式調用方法后,根據具體返回值的類型來確定的。見:

    Replay DefaultRemoter.execute(Call) 方法中的
    Object reply = chain.doFilter(object, method, call.getParameters()); 再進入到
    Object ExecuteAjaxFilter.doFilter(Object obj, Method method, Object[] params Ajax FilterChain){
          return method.invoke(obj, params);
    }

    就是根據上面的返回值,然后在

    DefaultConverterManager.convertOutbound(Object, OutboundContext) 方法中的

    Converter converter = getConverter(object);  //根據返回值 object  確定該用的 Converter。

    3. DWR Converter 的調用

    多留意下 DWR 自帶的 Converter,可以看到所有的 Converter 直接或簡接的 extends BaseV20Converter implements Converter,其實 BaseV20Converter(DWR 1.x 中對應為 BaseV10Converter) 本身就實現了 Converter。在 BaseV20Converter 抽象類中默認實現了 Converter 的方法

    public void setConverterManager(ConverterManager config)  {  }

    具體的 Converter 只要專心去實現接口 Converter 中的另兩個方法:

    Object convertInbound(Class paramType, InboundVariable data, InboundContext inctx) throws MarshallException;
    OutboundVariable convertOutbound(Object data, OutboundContext outctx) throws MarshallException;

    運行時,它們相應的被 ConvertManager(默認為 DefaultConvertManager) 的
    Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx, TypeHintContext incc) throws MarshallException
    OutboundVariable convertOutbound(Object object, OutboundContext outctx) throws MarshallException
    來調用。

    DWR 對每個參數或返回值至少會應用一次 Converter,但對于復雜的類型會遞歸的調用 Converter,比如,要完成

    JS "{id:123, name: 'Unmi', blogs:['http://unmi.blogjava.net','http://blog.csdn.net/kypfos']}"  到 Java 的 Person{int id, String name, String[] blogs;} 的轉換,就會使用到 bean->primitive->array 三個 Converter。

    4. 定制自己的 Converter

    基本上 DWR  內置的 Converter 就夠用的,但也有可能需要定定自己的 Converter。從 DWR 的 Converter 實現來看,一般會用兩種方式:

    1) extends BaseV20Converter implements Converter,實現 Converter 的 converterInbound() 和 converterOutbound() 方法
    2) extends BasicObjectConverter implements Converter,或繼承 BeanConverter,實現 BasicObjectConverter 的 getPropertyMapFromObject(),getPropertyMapFromObject() 和 createTypeHintContext() 方法。

    前一種方式,請參照 org.directwebremoting.convert.DateConverter 的源碼實現:

    convertInbound() 由 JS 的字符串轉換成要求的 Date、Time、Timestamp 或 Calender 對像。
    convertOubound() 把 Java 的類型轉換成 JS 的 new Date() 類型,注意返回值的寫法:
                                 return new SimpleOutboundVariable("new Date(" + millis + ")", outctx, true);

    第二種繼承 BasicObjectConverter 或是 BeanConverter 的做法,可參考 BeanConverter  的源碼實現。表現在 JSON 和 Java 對象間的轉換,要是引入解析 JSON 的 JAR 包或許能有不少幫助。

    定制 Converter 的內容講的很少,主要是真有這方面的需要的時候請參考 DWR  的相關源碼,實際中理解各個接口方法參數的意義,及返回值的要求。對待開源組件還是要保持閱讀源碼的好習慣。

    好啦,自己的 Converter 寫好,需要注冊,需要應用。我們還是參考 DWR 的做法,寫在自己的 dwr.xml 中。例如定制了 com.unmi.dwr.converter.SpecialConverter,要對 com.unmi.model.SpecialObject 進行出入類型的轉換,就這么寫:

    <converter id="special" class="com.unmi.dwr.converter.SpecialConverter"/> 注冊了 special 轉換器
    <convert converter="special" match="com.unmi.model.SpecialObject"/> 應用注冊的 special 轉換器應用到 com.unmi.model.SpecialObject  類型

    5. 小結

    用 DWR 其實也有段時日了,未曾系統的學,總是遇一問題、掃除一個,不免也會去找找相關更系統的資料。然而著下此篇的動機是上周六在書城翻了下 《 DWR 實戰》,它實際講 DWR 本身的較少。最后我第一個想了解了是 DWR 能完成 JS 與 Java 間什么類型的轉換,第一手的資料網上也沒搜索到,于是進到源碼中去,親身歷練,也更加深了印象。

    讀者也許和我一樣目的,只想看看內置的轉換器有哪些,能轉換哪些類型,那就只需看最為搶眼的那張表格吧。需要定制 Converter 應該很少,就像我們很少定制 Struts 的 Converter、Hibernate 的 UserType 和 iBatis 的 TypeHandler 一樣。因此也就對定制 DWR 的 Converter 所用篇幅不多。

    對待開源,自己總有個習慣就是必須有相關的源代碼伴隨在它身邊。開源組件的使用一般不難,碰到問題,既然源碼都掌握了,我想總能從源碼中找出原因來。尚且,對這樣的知名組件越發深入,就更能嚼出許多味多。


    參考:DWR 2.0.5 的源代碼,對 DWR 項目進行單步調試


    原文:http://www.tkk7.com/Unmi/archive/2009/06/23/283741.html


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


    網站導航:
     
    主站蜘蛛池模板: 人妻仑乱A级毛片免费看| 亚洲乱码一二三四五六区| 老司机午夜精品视频在线观看免费| 久久久久免费看黄A片APP| 亚洲国产精品久久网午夜| 日本妇人成熟免费中文字幕| 77777午夜亚洲| 在线观看免费精品国产| 一级毛片在播放免费| 亚洲热线99精品视频| 99久久国产精品免费一区二区| 亚洲av中文无码乱人伦在线播放| 色www永久免费网站| 一区二区三区亚洲| 久久WWW免费人成人片| 亚洲av无码成人精品区一本二本| 日本免费网站观看| 久草免费福利在线| 亚洲国产精品美女| 又粗又大又长又爽免费视频| 精品熟女少妇aⅴ免费久久| 亚洲日本一区二区三区| 美女视频黄a视频全免费| 精品久久久久久亚洲中文字幕| 国产中文在线亚洲精品官网| 日本在线免费观看| 国产亚洲精品bv在线观看| 亚洲成?Ⅴ人在线观看无码| 精品免费视在线观看| 亚洲va在线va天堂成人| JLZZJLZZ亚洲乱熟无码| 99精品视频免费在线观看| 亚洲性色AV日韩在线观看| 国产成人精品亚洲精品| 精品国产污污免费网站aⅴ| 久久精品国产亚洲AV| 九月丁香婷婷亚洲综合色| 四虎成人免费网站在线| 97无码人妻福利免费公开在线视频| 国产精品亚洲综合久久| 国产亚洲成av片在线观看|