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

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

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

    隨筆 - 42  文章 - 71  trackbacks - 0
    <2008年7月>
    293012345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    常用鏈接

    留言簿

    隨筆檔案

    文章分類(lèi)

    文章檔案

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    AXIS 1.4 自定義序列化/反序列化類(lèi)

    Technorati 標(biāo)簽: axis,customized,serializer,deserializer,web service

    現(xiàn)在在SOA被大肆鼓吹的時(shí)代,再加上確實(shí)企業(yè)級(jí)應(yīng)用平臺(tái)中不同系統(tǒng)間的整合越來(lái)越多,所以Web Service的地位日益上升。雖然效率上會(huì)有所折扣,但是畢竟是一個(gè)標(biāo)準(zhǔn),而且主流的編程語(yǔ)言本身或者加上一些框架都支持Web Service,無(wú)論是Server端還是Client端。記得在2001年底就做過(guò)一個(gè)Java Web Service Client調(diào)用Delphi Web Service Server,但是現(xiàn)在后悔的是當(dāng)時(shí)對(duì)于Web Service沒(méi)有認(rèn)真學(xué)習(xí),只是停留在淺嘗輒止的地步,正是應(yīng)了古人的那句:“書(shū)到用時(shí)方覺(jué)少”啊。

    現(xiàn)在的項(xiàng)目就是遇到這個(gè)情況,大量的跨系統(tǒng)的通訊都是通過(guò)Web Service。偏偏有些服務(wù)端編寫(xiě)的比較奇怪,而AXIS生成的客戶(hù)端又更加的奇怪。遇到的問(wèn)題是這樣的,服務(wù)端返回的數(shù)據(jù)中,有幾個(gè)類(lèi)型為xsd:dateTime,AXIS映射到Java的類(lèi)是java.util.Calendar。偏偏服務(wù)器有時(shí)候有的字段是不會(huì)帶有任何數(shù)據(jù)的,有的字段是一個(gè)字符"T"(因?yàn)閃eb Service中傳輸dateTime類(lèi)型的數(shù)據(jù)字符串格式為yyyy-MM-dd'T'hh:mm:ss.SSS,例如2008-07-24T23:49:15.000),也就是應(yīng)該生成對(duì)應(yīng)Java的null對(duì)象。可能是考慮到和.NET客戶(hù)端的兼容性吧(.NET不熟悉,但是為了解決這個(gè)問(wèn)題查看一些資料,都是說(shuō)對(duì)于dateTime類(lèi)型,如果是空,會(huì)在.NET的客戶(hù)端出現(xiàn)問(wèn)題),AXIS在處理無(wú)數(shù)據(jù)的dateTime類(lèi)型的節(jié)點(diǎn)時(shí),就粗暴的報(bào)錯(cuò)了。沒(méi)辦法,服務(wù)器端是沒(méi)有辦法改程序了,只好在客戶(hù)端下手了,反正這幾個(gè)字段對(duì)于我的客戶(hù)端不是很重要,只要不要因?yàn)檫@幾個(gè)特殊的數(shù)據(jù)影響了其它數(shù)據(jù)。

    第一個(gè)反應(yīng)就是修改AXIS的代碼,但是這種方案是不到萬(wàn)不得已是不能用的,太危險(xiǎn)了。然后就看AXIS的文檔以及API,看到有typeMapping的配置項(xiàng),但是對(duì)于其中的各個(gè)屬性又沒(méi)有詳細(xì)闡述,網(wǎng)上的例子大部分都是針對(duì)服務(wù)器端的。經(jīng)過(guò)詢(xún)問(wèn)其它同事,他們也遇到了類(lèi)似的問(wèn)題,他們定了自己的序列化/反序列化類(lèi),然后在AXIS產(chǎn)生的客戶(hù)端Stub代碼中以服務(wù)命名的方法,例如process方法插入自定義的序列化/反序列化類(lèi):

    public XXResponse process(XXRequest req) throws java.rmi.RemoteException {
            if (super.cachedEndpoint == null) {
                throw new org.apache.axis.NoEndPointException();
            }
            org.apache.axis.client.Call _call = createCall();
            _call.setOperation(_operations[0]);
            _call.setUseSOAPAction(true);
            _call.setSOAPActionURI("process");
            _call.setEncodingStyle(null);
            _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR,
                    Boolean.FALSE);
            _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS,
                    Boolean.FALSE);
            _call
                    .setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
            _call.setOperationName(new javax.xml.namespace.QName("", "process"));

    WsUtil.prepareCall(_call); // 這一句是用來(lái)插入自定義的Serializer和Deserializer
            setRequestHeaders(_call);

    看看WsUtil的prepareCall如何編寫(xiě)的:

    public class WsUtil {
        public static void prepareCall(org.apache.axis.client.Call _call) {
            _call.registerTypeMapping(
                            java.util.Date.class,
                            new javax.xml.namespace.QName("                            new CalendarSerializerFactory(java.util.Date.class, new javax.xml.namespace.QName(                            new CalendarDeserializerFactory(java.util.Date.class, new javax.xml.namespace.QName(        _call.registerTypeMapping(
                            java.util.Calendar.class,
                            new javax.xml.namespace.QName("
                            new CalendarSerializerFactory(java.util.Date.class,
                              new javax.xml.namespace.QName(
                              new CalendarDeserializerFactory(java.util.Date.class, new javax.xml.namespace.QName("    }

    這里,通過(guò)調(diào)用org.apache.axis.client.Call對(duì)象的registerTypeMapping方法來(lái)插入自定義的Serializer和Deserializer。(以上代碼感謝我不認(rèn)識(shí)的那位同事無(wú)私的奉獻(xiàn)和幫助)

    但是這種方法有一個(gè)問(wèn)題就是如果重新生成了客戶(hù)端代碼,需要在Stub類(lèi)中插入,也是比較具有破壞性的。我就覺(jué)得總有一個(gè)方法是比較優(yōu)雅的解決這個(gè)問(wèn)題的,然后順著這個(gè)思路繼續(xù)往下找,發(fā)現(xiàn)可以在Service locator類(lèi),也即extends了org.apache.axis.client.Service的那個(gè)類(lèi)來(lái)獲取到TypeMappingRegistery,于是,不再修改Stub類(lèi),在調(diào)用者代碼中,生成locator對(duì)象之后,調(diào)用注冊(cè)TypeMapping的方法:

    LabService locator = new LabServiceLocator();
            TypeMappingRegistry tmr = locator.getTypeMappingRegistry();
            TypeMapping tm = tmr.getDefaultTypeMapping();

            tm.register(java.util.Date.class, new QName(
                            "
                            new CustomizedCalendarSerializerFactory(java.util.Date.class,
                                    new javax.xml.namespace.QName(
                                            "
                            new CustomizedCalendarDeserializerFactory(
                                    java.util.Date.class,
                                    new javax.xml.namespace.QName(
                                            "
            tm.register(java.util.Calendar.class, new QName(
                    "
                    new CustomizedCalendarSerializerFactory(java.util.Calendar.class,
                            new javax.xml.namespace.QName(
                                    "
                    new CustomizedCalendarDeserializerFactory(
                            java.util.Calendar.class,
                            new javax.xml.namespace.QName(
                                    "
    通過(guò)測(cè)試,發(fā)現(xiàn)此方法可行,基本上比較好了,但是如果這么多的Service每次調(diào)用都干這么一件事,也是很麻煩的,而且,如果以后又有其它的自定義Serializer和Deserizlizer,還得修改代碼。于是乎繼續(xù)尋找更好的解決辦法。仔細(xì)閱讀AXIS的文檔,發(fā)現(xiàn)還有client-config.wsdd可用。在AXIS的代碼中,

    org/apache/axis/client/client-config.wsdd

    給出了一個(gè)樣本,但是是基本的配置,copy這個(gè)樣本到你的工程的source文件夾,不需要包即可,只要AXIS在運(yùn)行的時(shí)候,能夠在classes目錄找到這個(gè)文件就可以。

    以下是配置文件及相關(guān)類(lèi)的代碼:

    client-config.wsdd:(為了確保安全,把java.util.Date和java.util.Calendar都注冊(cè)了, 如果服務(wù)器端沒(méi)有強(qiáng)制指定encodingStyle,就把encodingStyle屬性設(shè)置為"",不知道為什么,改天抽時(shí)間再研究:P)

    ----------------------------------------------------------------------------------

    <deployment xmlns="
        xmlns:java="

        xmlns:xsd="
    >
        <globalConfiguration>
            <parameter name="disablePrettyXML" value="false" />
        </globalConfiguration>
        <transport name="http"
            pivot="java:org.apache.axis.transport.http.HTTPSender" />
        <transport name="local"
            pivot="java:org.apache.axis.transport.local.LocalSender" />
        <transport name="java"
            pivot="java:org.apache.axis.transport.java.JavaSender" />
        <typeMapping
            encodingStyle="

            languageSpecificType="java:java.util.Date"
            qname="xsd:dateTime" classname="java.util.Date"
            serializer="lab.serviceclient.mis.CustomizedCalendarSerializerFactory"
            deserializer="lab.serviceclient.mis.CustomizedCalendarDeserializerFactory" />
        <typeMapping
            encodingStyle="

            languageSpecificType="java:java.util.Calendar"
            qname="xsd:dateTime" classname="java.util.Calendar"
            serializer="lab.serviceclient.mis.CustomizedCalendarSerializerFactory"
            deserializer="lab.serviceclient.mis.CustomizedCalendarDeserializerFactory" />
    </deployment>

    ----------------------------------------------------------------------------------

    在client-config.wsdd樣本的基礎(chǔ)上修改的。

    languageSpecificType="java:java.util.Date"以及l(fā)anguageSpecificType="java:java.util.Calendar"表明映射到Java中哪種類(lèi)型的數(shù)據(jù)要求使用自定義的Serializer和Deserializer。注意寫(xiě)法,前面有name space "java",

    qname就是指返回的XML文件中的節(jié)點(diǎn)類(lèi)型,對(duì)于dateTime類(lèi)型的全稱(chēng)就是xsd:dateTime,其中xsd=serializer和deserializer節(jié)點(diǎn)是指向你的自定義serializer和deserializer的工廠類(lèi),而不是serializer和deserializer類(lèi)本身,這個(gè)要注意。

    由于不需要序列化的自定義,所以一開(kāi)始我用的AXIS原有的CalendarSerializerFactory,但是發(fā)現(xiàn)有問(wèn)題,參考CustomizedCalendarSerializerFactory中create方法的注釋不分。所以后來(lái)還是加上了自定義的Serializer,但是很簡(jiǎn)單了(注意繼承的父類(lèi)):

    CustomizedCalendarSerializer.java:

    ----------------------------------------------------------------------------------

    package lab.serviceclient.mis;

    import org.apache.axis.encoding.ser.CalendarSerializer;

    public class CustomizedCalendarSerializer extends CalendarSerializer {

        private static final long serialVersionUID = 1L;

    }

    ----------------------------------------------------------------------------------

    CustomizedCalendarSerializerFactory.java:

    ----------------------------------------------------------------------------------

    package lab.serviceclient.mis;

    import javax.xml.namespace.QName;

    import org.apache.axis.encoding.ser.BaseSerializerFactory;

    public class CustomizedCalendarSerializerFactory extends BaseSerializerFactory {

        private static final long serialVersionUID = 1L;

        public CustomizedCalendarSerializerFactory(Class javaType, QName xmlType) {
            super(CustomizedCalendarSerializer.class, xmlType, javaType);
        }

        // 這個(gè)static的create方法是必須的。如果使用前面介紹的編程注冊(cè)TypeMapping的方式,就不需要這個(gè)create方法;如果是定義在client-config.wsdd文件中,

        //AXIS在初始化的時(shí)候,org.apache.axis.deployment.wsdd.WSDDDeployment.deployMapping方法會(huì)調(diào)用factory的create方法,如果沒(méi)有這個(gè)方法,就不能注冊(cè)成功

        // 對(duì)于Deserializer也是一樣的
        public static CustomizedCalendarSerializerFactory create(Class javaType, QName xmlType) {
            return new CustomizedCalendarSerializerFactory(javaType, xmlType);
        }

    }

    ----------------------------------------------------------------------------------

    CustomizedCalendarDeserializer.java

    ----------------------------------------------------------------------------------

    package lab.serviceclient.mis;

    import javax.xml.namespace.QName;

    import org.apache.axis.encoding.ser.CalendarDeserializer;

    public class CustomizedCalendarDeserializer extends CalendarDeserializer {

        private static final long serialVersionUID = 1L;

        public CustomizedCalendarDeserializer(Class javaType, QName xmlType) {
            super(javaType, xmlType);
        }
        public Object makeValue(String source) {
            System.out.println("========= This is the Customized Calendar Deserializer ========="); //為了測(cè)試是否到達(dá)了自定義的類(lèi)
            if ( source == null || source.length() == 0 || "T".equals(source)) return null;
            return super.makeValue(source);
        }
    }

    ----------------------------------------------------------------------------------

    CustomizedCalendarDeserializerFactory.java

    ----------------------------------------------------------------------------------

    package lab.serviceclient.mis;

    import javax.xml.namespace.QName;

    import org.apache.axis.encoding.ser.BaseDeserializerFactory;
    import org.apache.axis.encoding.ser.CalendarDeserializer;

    public class CustomizedCalendarDeserializerFactory extends BaseDeserializerFactory {
        private static final long serialVersionUID = 1L;

        public CustomizedCalendarDeserializerFactory(Class javaType, QName xmlType) {
            super(CustomizedCalendarDeserializer.class, xmlType, javaType);  
        }
        public static CustomizedCalendarDeserializerFactory create(Class javaType, QName xmlType) {
            return new CustomizedCalendarDeserializerFactory(javaType, xmlType);
        }
    }

    ----------------------------------------------------------------------------------

    有了這個(gè)方法,就可以不擔(dān)心服務(wù)器端返回奇怪的數(shù)據(jù)了。


    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 人与动性xxxxx免费| 在免费jizzjizz在线播| 亚洲AV无码久久精品蜜桃| 日本妇人成熟免费中文字幕| 国产成人+综合亚洲+天堂| 久久精品亚洲日本佐佐木明希| 91嫩草国产在线观看免费| 一区二区视频在线免费观看| 久久久亚洲AV波多野结衣| 日本媚薬痉挛在线观看免费| 久久免费精品一区二区| 精品亚洲av无码一区二区柚蜜| 久久久久无码精品亚洲日韩 | 精品熟女少妇aⅴ免费久久 | 亚美影视免费在线观看| 亚洲男女性高爱潮网站| 国产专区一va亚洲v天堂| 欧美a级在线现免费观看| 最新久久免费视频| 亚洲成在人线在线播放无码 | 福利免费在线观看| 亚洲国产精品无码久久九九大片| 久久亚洲免费视频| 亚洲色欲久久久久综合网| 最近最新的免费中文字幕| 日韩av无码久久精品免费| 一个人看的www视频免费在线观看 一个人看的免费观看日本视频www | 99爱视频99爱在线观看免费 | 成年在线网站免费观看无广告| 最近免费中文字幕MV在线视频3| 国产亚洲欧美日韩亚洲中文色| 亚洲高清无在码在线电影不卡| 亚洲中文字幕在线第六区| 国产在线不卡免费播放| 精品女同一区二区三区免费站| 叮咚影视在线观看免费完整版| 日产久久强奸免费的看| 国产精品无码亚洲精品2021 | 亚洲国产成人精品电影| 亚洲av日韩av天堂影片精品| 永久亚洲成a人片777777 |