如何通過J2ME來實現訪問webservice比較常用的方法使用ksoap或者是支持JSr172的直接使用哪個ws包就行了。訪問.Net創建的webservice比較麻煩。如果是支持JSr172的設備可以使用wtk2.2直接生成樁,就是生個stub和幾個訪問類就可以實現對webservice的訪問,但要注意返回類型,如果webservice的返回類型不是wtk能支持的話就會生成失敗。
如果不支持JSr172的就比較麻煩,可以使用ksoap來做soap協議解析,完成對webservice訪問。我試用了ksoap2不知道老是不成功,報錯誤是因為kxml中的XMLpull有問題。找不到哪個v11的類。感覺用ksoap2會是一個訪問.net webservice的好選擇,因為它內置了.Net支持的選擇,可以配置rpc與net選擇。但是因為不成功,所以不能不轉到ksoap來想辦法。
使用它的例子程序作了一個helloworld程序,呵呵不成功,改造它的httptransport類,將發送和接收的soap包打印處出進行比較,發現是soap標簽不一致,我用.net的webservice支持的soap標簽是soapenc之類的,而使用ksoap打出來的包都是SOAP-ENC之類的。沒辦法手工改吧。修改org.ksoap.soap.Java文件找到SOAP-ENC,SOAP-ENV之類的改成soapenc,soapenv之類。改完了運行,還是出錯,察看輸入soap包比對.Net webservice要求的soap包發現包頭少了不少東西。發現該問題是org.kxml.parser.AbstractXMLParser.Java文件中public void startTag (PrefixMap prefixMap,String namespace, String name) 方法有問題,其中有個do,while循環存在問題
修改為
do {
String p2 = current.getPrefix ();
String ns = current.getNamespace ();
if (!ns.equals (oldMap.getNamespace (p2))) {
attribute (p2.equals ("") ? "xmlns" : ("XMLns:"+p2), ns);
}
current = current.getPrevious ();
}
while (current != null && current != oldMap);
原有方法沒有將當前PrefixMap的後繼PrefixMap中信息寫入所以導致一個標簽內的信息不全。修改後運行還是存在問題,根據返回soap包內容發現改造後的包頭竟然有兩項重復出現,經檢查為soap.Java內初始化PrefixMap數組時存在問題,原有方法定義一個basePrefixMap,而下面在個協議中使用該PrefixMap構造,所以導致V11與V12版本的soap包頭重復出現soapenv與soapenc修改之
public static final PrefixMap [] prefixMap = {
new PrefixMap (new PrefixMap
(basePrefixMap, "xsd", XSD1999), "xsi", XSI1999),
new PrefixMap (new PrefixMap (new PrefixMap (new PrefixMap
(PrefixMap.DEFAULT, "xsd", XSD), "xsi", XSI), "soap", ENV), "soapenc", ENC),
new PrefixMap (new PrefixMap (new PrefixMap (new PrefixMap
(PrefixMap.DEFAULT, "xsd", XSD), "xsi", XSI), "soap", ENV2001), "soapenc", ENC2001)};
這樣就好了,哈哈。不過運行還是出錯。是enc與env的協議不匹配,呵呵我用的V12也就是2001沒想到竟然不對,改用V11後問題解決,不過不是可以運行,使這個問題不出了,出現另外問題,soap返回fault代碼是soapAction不存在,比對後發現,比較變態的說,這個SoapAction必須和.Net webservice給出的一樣才行,而且有些是namespace+method有些不是。累,指定SoapAction為namespace+method,例如這個SoapAction就是"http://ww.tmp.com/method",而那個url就是http://yourserver/yourservice.asmx;這樣終於可以訪問了。
漏了一句,如果想要訪問.Net的webservice我用的[WebMethod,SoapRpcMethod]在每個需要訪問的服務方法上面。如果不添那個SoapRpcMethod就不能用呀。
終於搞定。