java調用.net寫的webserver接口(.asmx后綴)


  之前項目上一直調用的是java代碼寫的接口,方法一直沒有問題,這次調用.asmx后綴的.net接口的時候,原來的方法在創建連接的時候就已經出錯,百度得到很多答案,在此整理一下。

一、使用axis1.x調用webservice方法 
Axis的最常用版本:1.4和2.0版本。以下為1.4版本 

1.所需jar包

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")); 

// 該方法需要的參數 

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); 

// 方法的返回值類型 

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開發人員一樣的開發效率。 

核心代碼: 

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包了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM