以前項目上一直調用的是java代碼寫的接口,方法一直沒有問題,此次調用.asmx後綴的.net接口的時候,原來的方法在建立鏈接的時候就已經出錯,百度獲得不少答案,在此整理一下。java
1、使用axis1.x調用webservice方法
Axis的最經常使用版本:1.4和2.0版本。如下爲1.4版本 web
1.所需jar包apache
maven倉庫國內鏡像地址:https://mvnrepository.com/數組
2.相關代碼瀏覽器
核心代碼:
// webserviceURL 服務器
// 指出service所在完整的URL String url= "http://xxx/WebService.asmx"; Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(new java.net.URL(url));
// 設置要調用的方法 網絡
// http://tempuri.org/是wsdl中definitions根節點的targetNamespace屬性值 call.setOperationName(new QName("http://tempuri.org/","addProductRepStage"));
// 該方法須要的參數 app
call.addParameter("CustNo", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); call.addParameter("passwd", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); call.addParameter("Jobno", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
// 方法的返回值類型 maven
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING); // call.setUseSOAPAction(true); // call.setSOAPActionURI("http://tempuri.org/addProductRepStage"); // 調用該方法, new Object[] { CustNo, passwd, Jobno}爲參數列表 String xmlStr = call.invoke(new Object[] { CustNo, passwd, Jobno}).toString(); } catch (Exception e) { e.printStackTrace(); }
JAVA用這種方式調用webservice,須要注意的地方:
1. 服務器未能識別 HTTP 標頭 SOAPAction 的值:
症狀一:
Web Service + ASP.NET 應用程序部署到服務器默認目錄中,在IE中用http://<服務器地址>/<程序目錄名>/<默認啓動頁面名>發生「服務器未能識別 HTTP 標頭 SOAPAction 的值」錯誤。
症狀二:
在Java平臺上調用.NET Web Service的服務時,出現"服務器未能識別 HTTP 標頭 SOAPAction 的值"。
症狀三:
在Java平臺下調用.NET WEB Service,出現數據時有時無。
解決對策:
給.NET的WebService類(即.asmx文件下的類)添加屬性[SoapDocumentService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)]
小知識:
什麼是SoapAction?它在WSDL中有何做用?
SOAPAction HTTP request header被用來標識SOAP HTTP請求的目的地,其值是個URI地址。SOAP發送並不限制格式、URI特徵或其必須可解析,那麼在這種狀況下,發送一個HTTP SOAP請求時,其HTTP客戶端必須使用/指明SOAPAction HTTP request header。
SOAPAction header的內容能夠被用在服務端,諸如:防火牆適當的過濾基於HTTP的SOAP請求消息等場景。SOAPAction header的值爲空串("")表示SOAP消息的目的地由HTTP請求的URI標識;無值則表示沒有指定這條消息的目的地。
補充說明:
在.NET環境調用.NET WebService出現 「SOAPAction 值在 XML Web services 的全部方法中不惟一的錯誤」,也能夠經過此法解決。
2. 爲了Java可以調用WebService的方法,因此.NET寫的WebServiced的每一個方法都要聲明爲Rpc方法,即添加"[SoapRpcMethod.....]".
例如:[WebMethod]
[SoapRpcMethod(Use=SoapBindingUse.Literal,Action= http://tempuri.org/HelloWorld", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/")]
3. 對返回值、參數的處理上:
應儘可能將webservice方法的返回值、參數都寫成字符串(String)不要使用複雜對象類型,這樣便於在網絡上傳輸。避免了複雜對象類型的不易轉換問題。。。對於返回類型是字符串數組型的,能夠設置返回類型爲org.apache.axis.encoding.XMLType.SOAP_VECTOR或java.lang.String[].class.
二.利用xfire調用WebService
XFire是新一代的Java Web服務引擎,XFire使得在JavaEE應用中發佈Web服務變得垂手可得。和其餘Web服務引擎相比,XFire的配置很是簡單,能夠很是容易地和Spring集成,它使得Java開發人員終於能夠得到和.Net開發人員同樣的開發效率。
核心代碼: url
Service service = new ObjectServiceFactory().create(IWebservice.class); XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire()); String url= "http://localhost:8080/webservices/services/webservices"; IWebservice iw = (IWebservice) factory.create(service, url); List list=iw.getTest();
完整示例代碼:
package avicit.mms.common; import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.client.Call; import org.apache.axis.client.Service; public class Test { public static void main(String[] args) { Textaxis(); } //經過axis方式調用webservice接口 public static void Textaxis() { try { StringBuffer xml = new StringBuffer(); xml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\n"); xml.append("<stages>\n"); xml.append("..."); xml.append("</stages>\n"); // 指出service所在完整的URL String url = "http://127.0.0.1:9080/xxx/WebService.asmx"; //調用接口的targetNamespace //targetNamespace 就是你用瀏覽器打開url 路徑加上?wsdl,即http://xxx/WebService.asmx?wsdl 中的targetNamespace屬性值 String targetNamespace = "http://tempuri.org/"; //所調用接口的方法method String method = "addProductRepStage"; // 建立一個服務(service)調用(call) Service service = new Service(); Call call = (Call) service.createCall();// 經過service建立call對象 // 設置service所在URL call.setTargetEndpointAddress(new java.net.URL(url)); //設置要調用的方法 call.setOperationName(new QName(targetNamespace, method)); //設置要返回的數據類型 call.setReturnType(new QName(targetNamespace, method), String.class); call.setUseSOAPAction(true); call.setSOAPActionURI(targetNamespace+method); //變量最好只是用String類型,其餘類型會報錯,這裏的proRepStageInfoXml是.net接口中須要的參數名 call.addParameter(new QName(targetNamespace, "proRepStageInfoXml"), Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);//設置參數名 proRepStageInfoXml 第二個參數表示String類型,第三個參數表示入參 //調用方法並傳遞參數 String flag = (String) call.invoke(new Object[] {xml.toString()});//此處爲數組,有幾個變量傳幾個變量 System.out.println(flag); } catch (Exception e){ e.printStackTrace(); } } }
這兩天發現一個問題,因此在此備註一下,Axis的jar包中的axis-wsdl4j-1.5.1和cxf調用接口中要用到的wsdl4j-1.6.2有衝突,版本多少其實不重要,就是兩個jar包裏面的類差很少,因此若是有高版本的wsdl4j的jar包,就不須要在引axis-wsdl4j-1.5.1的jar包了。