竹十一
          在匆忙與奔走中墮落
          如何通過(guò)SOAP發(fā)送二進(jìn)制數(shù)據(jù)?

          只要web services需要發(fā)送/接受二進(jìn)制數(shù)據(jù)就會(huì)遇到。解決辦法也很直接:或者把二進(jìn)制數(shù)據(jù)通過(guò)Base64轉(zhuǎn)到文本,或者通過(guò)附件的方式發(fā)送。

          Base64方式比較簡(jiǎn)單易用,但是生成的文本對(duì)應(yīng)二進(jìn)制數(shù)據(jù)體積有三成以上的膨脹。發(fā)送很小二進(jìn)制數(shù)據(jù)的時(shí)候可以應(yīng)用,因?yàn)楹?jiǎn)單,數(shù)據(jù)體積一般也不會(huì)超出可接受范圍。

          SOAP with Attachments是另一種方式,很類似發(fā)送email的附件。這種做法有效而標(biāo)準(zhǔn),不過(guò)它在設(shè)計(jì)上有個(gè)缺陷,附件并不作為SOAP消息的一部分被發(fā)送,類似在SOAP消息里面?zhèn)鱾€(gè)二進(jìn)制數(shù)據(jù)的URL,然后通過(guò)這URL得到對(duì)應(yīng)的二進(jìn)制數(shù)據(jù)。這可在互操作性上有些問(wèn)題,比如和WS-Security協(xié)作時(shí)可能控制不到外部的二進(jìn)制數(shù)據(jù)。

          MTOM(Message Transmission Optimization Mechanism)是在SOAP with Attachment之后一種更好的解決方案。它通過(guò)XOP(XML-binary Optimized Packaging)方式來(lái)實(shí)現(xiàn)二進(jìn)制數(shù)據(jù)的傳輸。XOP也是將二進(jìn)制數(shù)據(jù)放在XML文檔外面,但它通過(guò)在XML文檔中添加X(jué)OP:include元素告訴XML處理器使用二進(jìn)制數(shù)據(jù)替換特定的內(nèi)容,這樣就使得二進(jìn)制數(shù)據(jù)的處理方式與文本數(shù)據(jù)的處理方式一致。

          下面的代碼片段是簡(jiǎn)單的用法示例片段:
          Server端代碼:
                  OMFactory messageFactory = OMAbstractFactory.getOMFactory();
                  OMNamespace ns 
          = messageFactory.createOMNamespace("urn:foo" , "foo");
                  OMElement binEle 
          = messageFactory.createOMElement("payload",ns);
                  File att 
          = new File("someBinaryData");
                  log.info(
          "is attachement exist? = " + att.exists());
                  FileDataSource src 
          = new FileDataSource(att);
                  DataHandler handler 
          = new DataHandler(src);
                  OMText textNode 
          = messageFactory.createOMText(handler, true);
                  binEle.addChild(textNode);
                  element.addChild(binEle);
              如果要禁用MTOM,只要在對(duì)應(yīng)節(jié)點(diǎn)加上
                  textNode.setOptimize(false);
              就可以了,Axis2將使用Base64編碼來(lái)處理二進(jìn)制數(shù)據(jù)。
                 
          Client代碼:                   
              設(shè)置客戶端支持MTOM:
                  ServiceClient wsClient = new ServiceClient();
                  Options clientOptions 
          = new Options();
                  clientOptions.setTo(
          new EndpointReference("http://some/service"));
                  clientOptions.setAction(
          "foo");
                  clientOptions.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE); 
          // enable MTOM
                  wsClient.setOptions(clientOptions);
              取得二進(jìn)制數(shù)據(jù)的方法
                  OMElement dataElement = result.getFirstChildWithName(new QName("urn:foo""payload"));
                  OMText dataNode 
          = (OMText) dataElement.getFirstOMChild();
                  DataHandler handler 
          = (DataHandler) dataNode.getDataHandler();
                  InputStream is 
          = handler.getDataSource().getInputStream();
              Client通過(guò)MTOM傳輸二進(jìn)制數(shù)據(jù)到Server端的方法與Server端類似,只不過(guò)是把帶有二進(jìn)制數(shù)據(jù)的節(jié)點(diǎn)添加到要發(fā)送出去的OMElement上。

          Axis2配置
              在axis2.xml里面修改enableMTOM為true,默認(rèn)是false。
              <parameter name="enableMTOM">true</parameter>


          注:在應(yīng)用MTOM傳輸二進(jìn)制數(shù)據(jù)時(shí),可以注意到HTTP頭里面的消息類型是messageType=application/xop+xml。



          posted on 2007-12-20 00:09 竹十一 閱讀(3039) 評(píng)論(0)  編輯  收藏 所屬分類: SOA
           
          主站蜘蛛池模板: 德格县| 舞钢市| 乐至县| 德保县| 三河市| 乌什县| 额敏县| 陆丰市| 铜陵市| 若羌县| 曲沃县| 浙江省| 株洲市| 井陉县| 灵石县| 金华市| 乐山市| 黄陵县| 内江市| 旬阳县| 房产| 元江| 澎湖县| 申扎县| 平邑县| 潍坊市| 马边| 吉首市| 绵竹市| 桦南县| 康马县| 白山市| 堆龙德庆县| 新源县| 东丰县| 长丰县| 濮阳县| 福泉市| 东乡族自治县| 临桂县| 自治县|