我必须用 Java 开发几个 WS。因为我以前没有这方面的经验,所以我从一个简单的例子开始。这里是 WS:
@WebService
public interface DataExchangeWebService {
public int doubleIt(int numberToDouble);
}
@WebService(targetNamespace = "http://www.example.com/ws/DataExchange",
portName = "DataExchangePort",
serviceName = "DataExchangeService",
endpointInterface = "xyz.DataExchangeWebService")
public class DataExchangeWebServiceImpl implements DataExchangeWebService {
@Override
public int doubleIt(int numberToDouble) {
return numberToDouble * 2;
}
}
现在我只想通过 JUnit 测试这个服务。我找到了这个博客条目,它为我的测试用例构建了起点。为了简单起见,我使用了 Java Endpoint 类。
protected static URL wsdlURL;
protected static QName serviceName;
protected static QName portName;
protected static Endpoint endpoint;
protected static String address;
static {
serviceName = new QName("http://www.example.com/ws/DataExchange", "DataExchangeService");
portName = new QName("http://www.example.com/ws/DataExchange", "DataExchangePort");
}
@BeforeClass
public static void setUp() throws MalformedURLException {
address = "http://localhost:9000/ws/DataExchange";
wsdlURL = new URL(address + "?wsdl");
endpoint = Endpoint.publish(address, new DataExchangeWebServiceImpl());
}
@AfterClass
public static void tearDown() {
endpoint.stop();
}
这将发布 WS 并生成以下 WSDL:
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.1.6 in JDK 6. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.1.6 in JDK 6. -->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.com/ws/DataExchange" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.example.com/ws/DataExchange"
name="DataExchangeService">
<import namespace="http://dataexchange.sys.cs.iface.service.appserver.xyz/"
location="http://localhost:9000/ws/DataExchange?wsdl=1" />
<binding xmlns:ns1="http://dataexchange.sys.cs.iface.service.appserver.xyz/"
name="DataExchangePortBinding" type="ns1:DataExchangeWebService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="doubleIt">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="DataExchangeService">
<port name="DataExchangePort" binding="tns:DataExchangePortBinding">
<soap:address location="http://localhost:9000/ws/DataExchange" />
</port>
</service>
</definitions>
现在我有两个测试用例。第一个,使用普通服务发出请求:
public void raw_service() {
Service service = Service.create(wsdlURL, serviceName);
DataExchangeWebService dataExchangeWebService = service.getPort(portName, DataExchangeWebService.class);
int resp = dataExchangeWebService.doubleIt(10);
assertEquals(20, resp);
}
这个工作正常。有问题的是第二个。它使用 SOAP 消息发出请求:
public void raw_service_with_full_soap_message() throws DOMException, SOAPException, IOException {
Service service = Service.create(wsdlURL, serviceName);
Dispatch<SOAPMessage> disp = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
InputStream is = getClass().getClassLoader().getResourceAsStream("fullSOAPMessage.xml");
SOAPMessage reqMsg = MessageFactory.newInstance().createMessage(null, is);
assertNotNull(reqMsg);
SOAPMessage response = disp.invoke(reqMsg);
assertEquals("Double-It not doubling zero correctly", "0", response.getSOAPBody().getTextContent().trim());
}
fullSOAPMessage.xml 如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:doubleIt xmlns:ns2="http://www.example.com/ws/DataExchange">
<numberToDouble>0</numberToDouble>
</ns2:doubleIt>
</soap:Body>
</soap:Envelope>
JUnit 失败:
javax.xml.ws.soap.SOAPFaultException: Cannot find dispatch method for {http://www.example.com/ws/DataExchange}doubleIt
到目前为止,我所做的研究仅表明,这与 WS 的目标名称空间和 SOAP 消息之间的冲突有关。但在我看来,情况并非如此。关于如何解决这个问题或发生了什么的一些想法?