<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


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


    網站導航:
     
    主站蜘蛛池模板: 亚洲四虎永久在线播放| 国产亚洲AV夜间福利香蕉149| 日韩精品一区二区亚洲AV观看| 黄色短视频免费看| 亚洲午夜久久久影院| 中文字幕乱理片免费完整的| 亚洲日产无码中文字幕| 无码免费一区二区三区免费播放| 亚洲不卡av不卡一区二区| 亚洲人成免费网站| 国产精品亚洲专区在线观看| 蜜桃精品免费久久久久影院| 老司机福利在线免费观看| 亚洲一级特黄无码片| 久操免费在线观看| 亚洲三级视频在线观看| 日韩电影免费在线| 成年网在线观看免费观看网址| 久久精品亚洲乱码伦伦中文| 日韩电影免费在线观看| 亚洲国产日韩在线人成下载| 午夜a级成人免费毛片| 色妞www精品视频免费看| 亚洲精品亚洲人成在线观看| AV无码免费永久在线观看| 国产精品手机在线亚洲| 亚洲精品制服丝袜四区| 亚洲人成电影网站免费| 伊人久久国产免费观看视频| 亚洲一区二区三区夜色| 国产老女人精品免费视频| 99视频在线观看免费| 67194在线午夜亚洲| 亚洲国产中文v高清在线观看| 久久免费国产视频| 美女18毛片免费视频| 亚洲国产精品lv| 又粗又硬免费毛片| 91av视频免费在线观看| 美女露100%胸无遮挡免费观看| 亚洲Aⅴ无码专区在线观看q|