我想检查不同平台之间的 SOAP 互操作性;我是一名 Java 程序员,尤其不了解 C#。
我在 C# 中做了什么:
转移对象:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Serialization;
[XmlRoot]
public class Pack
{
private int id;
private string name;
public Pack()
{
}
public Pack(int anId, string aName)
{
this.id = anId;
this.name = aName;
}
public void setId(int anId)
{
this.id = anId;
}
public int getId()
{
return id;
}
public void setName(string aName)
{
this.name = aName;
}
public string getName()
{
return name;
}
}
网络服务:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Xml.Serialization;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class PackWS : System.Web.Services.WebService
{
private Dictionary<int, Pack> dictionary;
public PackWS()
{
dictionary = new Dictionary<int, Pack>();
}
[WebMethod]
[XmlInclude(typeof(String))]
public String getName()
{
return "Goodbye world!";
}
[WebMethod]
[XmlInclude(typeof(Pack))]
public void addPackage(Pack package)
{
dictionary.Add(package.getId(), package);
}
[WebMethod]
[XmlInclude(typeof(Pack))]
public Pack getPackage(int id)
{
return dictionary[id];
}
}
项目在指定的 URI 处构建和发布 wsdl。我添加了一个 Java 客户端部分:
转移对象:
package user;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Pack {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
界面:
package user;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService(targetNamespace = "http://tempuri.org/",
portName = "PackWSSoap",
wsdlLocation = "http://localhost:57265/Service.asmx?wsdl",
serviceName = "PackWS")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface PackWSSoap {
void addPackage(Pack pack);
Pack getPackage(int id);
String getName();
}
服务
package user;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;
public class PackageClient {
public static void main(String[] args) {
try {
URL url = new URL("http://localhost:57265/Service.asmx?wsdl");
QName qName = new QName("http://tempuri.org/", "PackWS");
Service service = Service.create(url, qName);
PackWSSoap packWS = service.getPort(PackWSSoap.class);
System.out.println(packWS.getName());//null here
packWS.addPackage(getPack());//C# exception here
System.out.println(packWS.getPackage(getPack().getId()));//unreachable
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
static Pack getPack() {
return new Pack(){{
setId(2);
setName("name");
}
};
}
}
调用该getName()
方法时,它应该返回一个简单的字符串,但它返回 null。当尝试通过调用添加包时,addPackage(pack)
我在客户端上收到来自 C# 的异常,在 Java 中:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at PackWS.addPackage(Pack package) in f:\DS Projects\ds5\NET\App_Code\PackWS.cs:line 38
--- End of inner exception stack trace ---
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:163)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:94)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:236)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:206)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:103)
at $Proxy18.addPackage(Unknown Source)
at user.PackageClient.main(PackageClient.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
我不认为沟通有什么问题,因为异常通过得很好;但我相信我没有向 .NET 服务器添加任何内容。任何帮助将不胜感激,并对长篇文章感到抱歉。
这是WSDL:
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="getName">
<s:complexType/>
</s:element>
<s:element name="getNameResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getNameResult" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="addPackage">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="package" nillable="true" type="tns:Pack"/>
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="Pack"/>
<s:element name="addPackageResponse">
<s:complexType/>
</s:element>
<s:element name="getPackage">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="id" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="getPackageResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="getPackageResult" nillable="true" type="tns:Pack"/>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="getNameSoapIn">
<wsdl:part name="parameters" element="tns:getName"/>
</wsdl:message>
<wsdl:message name="getNameSoapOut">
<wsdl:part name="parameters" element="tns:getNameResponse"/>
</wsdl:message>
<wsdl:message name="addPackageSoapIn">
<wsdl:part name="parameters" element="tns:addPackage"/>
</wsdl:message>
<wsdl:message name="addPackageSoapOut">
<wsdl:part name="parameters" element="tns:addPackageResponse"/>
</wsdl:message>
<wsdl:message name="getPackageSoapIn">
<wsdl:part name="parameters" element="tns:getPackage"/>
</wsdl:message>
<wsdl:message name="getPackageSoapOut">
<wsdl:part name="parameters" element="tns:getPackageResponse"/>
</wsdl:message>
<wsdl:portType name="PackWSSoap">
<wsdl:operation name="getName">
<wsdl:input message="tns:getNameSoapIn"/>
<wsdl:output message="tns:getNameSoapOut"/>
</wsdl:operation>
<wsdl:operation name="addPackage">
<wsdl:input message="tns:addPackageSoapIn"/>
<wsdl:output message="tns:addPackageSoapOut"/>
</wsdl:operation>
<wsdl:operation name="getPackage">
<wsdl:input message="tns:getPackageSoapIn"/>
<wsdl:output message="tns:getPackageSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PackWSSoap" type="tns:PackWSSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getName">
<soap:operation soapAction="http://tempuri.org/getName" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="addPackage">
<soap:operation soapAction="http://tempuri.org/addPackage" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPackage">
<soap:operation soapAction="http://tempuri.org/getPackage" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="PackWSSoap12" type="tns:PackWSSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getName">
<soap12:operation soapAction="http://tempuri.org/getName" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="addPackage">
<soap12:operation soapAction="http://tempuri.org/addPackage" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPackage">
<soap12:operation soapAction="http://tempuri.org/getPackage" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PackWS">
<wsdl:port name="PackWSSoap" binding="tns:PackWSSoap">
<soap:address location="http://localhost:57265/Service.asmx"/>
</wsdl:port>
<wsdl:port name="PackWSSoap12" binding="tns:PackWSSoap12">
<soap12:address location="http://localhost:57265/Service.asmx"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>