如何在Java中使用SOAP Web服务

19

请有人帮我提供一些链接和其他信息,说明如何在Java中使用Web服务WSDL。


可能是A simple java SOAP client的重复问题。 - Robert Munteanu
4个回答

12

有许多选项可以使用基于WSDL创建的存根或Java类来消耗SOAP Web服务。但是,如果有人想在没有创建任何Java类的情况下执行此操作,则本文非常有用。

文章中的代码片段:

public String someMethod() throws MalformedURLException, IOException {

//Code to make a webservice HTTP request
String responseString = "";
String outputString = "";
String wsURL = "<Endpoint of the webservice to be consumed>";
URL url = new URL(wsURL);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection)connection;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
String xmlInput = "entire SOAP Request";

byte[] buffer = new byte[xmlInput.length()];
buffer = xmlInput.getBytes();
bout.write(buffer);
byte[] b = bout.toByteArray();
String SOAPAction = "<SOAP action of the webservice to be consumed>";
// Set the appropriate HTTP parameters.
httpConn.setRequestProperty("Content-Length",
String.valueOf(b.length));
httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction", SOAPAction);
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
OutputStream out = httpConn.getOutputStream();
//Write the content of the request to the outputstream of the HTTP Connection.
out.write(b);
out.close();
//Ready with sending the request.

//Read the response.
InputStreamReader isr = null;
if (httpConn.getResponseCode() == 200) {
  isr = new InputStreamReader(httpConn.getInputStream());
} else {
  isr = new InputStreamReader(httpConn.getErrorStream());
}

BufferedReader in = new BufferedReader(isr);

//Write the SOAP message response to a String.
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
//Parse the String output to a org.w3c.dom.Document and be able to reach every node with the org.w3c.dom API.
Document document = parseXmlFile(outputString); // Write a separate method to parse the xml input.
NodeList nodeLst = document.getElementsByTagName("<TagName of the element to be retrieved>");
String elementValue = nodeLst.item(0).getTextContent();
System.out.println(elementValue);

//Write the SOAP message formatted to the console.
String formattedSOAPResponse = formatXML(outputString); // Write a separate method to format the XML input.
System.out.println(formattedSOAPResponse);
return elementValue;
}

如果您正在寻找一个类似的解决方案,可以在使用SOAP API时上传文件,请参考这篇文章:如何在SOAP POST请求中附加文件(pdf、jpg等)?


8
我将使用CXF,你也可以考虑使用AXIS 2。
最好的方法可能是使用JAX RS,请参考example
Example:

wsimport -p stockquote http://stockquote.xyz/quote?wsdl

This will generate the Java artifacts and compile them by importing the http://stockquote.xyz/quote?wsdl.

I


7
我觉得我的工作很有压力,但如果导入一个WSDL文件决定你的生死,那你的情况肯定更糟。哈哈。 - cbmeeks

5

这里有一个很好的教程,可以帮助你学习如何通过WSDL创建和使用SOAP服务。简而言之,您需要从命令行调用wsimport工具(您可以在jdk中找到它),并使用类似于-s(.java文件的源)-d(.class文件的目标)和wsdl链接的参数。

$ wsimport -s "C:\workspace\soap\src\main\java\com\test\soap\ws" -d "C:\workspace\soap\target\classes\com\test\soap\ws" http://localhost:8855/soap/test?wsdl

创建存根之后,您可以轻松调用webservices,就像这样:
TestHarnessService harnessService = new TestHarnessService();
ITestApi testApi = harnessService.getBasicHttpBindingITestApi();
testApi.resetLogMemoryTarget();

5

有人建议您可以使用Apache或JAX-WS。您也可以使用从WSDL生成代码的工具,例如ws-import,但在我看来,消费Web服务的最佳方法是创建动态客户端,并仅调用您想要的操作,而不是从wsdl中获取所有内容。您可以通过创建动态客户端来实现此操作:样例代码如下:

String endpointUrl = ...;

QName serviceName = new QName("http://com/ibm/was/wssample/echo/",
 "EchoService");
QName portName = new QName("http://com/ibm/was/wssample/echo/",
 "EchoServicePort");

/** Create a service and add at least one port to it. **/ 
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);

/** Create a Dispatch instance from a service.**/ 
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, 
SOAPMessage.class, Service.Mode.MESSAGE);

/** Create SOAPMessage request. **/
// compose a request message
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);

// Create a message.  This example works with the SOAPPART.
SOAPMessage request = mf.createMessage();
SOAPPart part = request.getSOAPPart();

// Obtain the SOAPEnvelope and header and body elements.
SOAPEnvelope env = part.getEnvelope();
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();

// Construct the message payload.
SOAPElement operation = body.addChildElement("invoke", "ns1",
 "http://com/ibm/was/wssample/echo/");
SOAPElement value = operation.addChildElement("arg0");
value.addTextNode("ping");
request.saveChanges();

/** Invoke the service endpoint. **/
SOAPMessage response = dispatch.invoke(request);

/** Process the response. **/

谢谢Maciej,但是一旦我导入WSDL,它会创建很多看起来非常复杂的类。有没有一个简单的技巧可以使用? - OyugiK
2
@user755611,我展示给你的代码没有导入任何类。它是一个动态客户端的外壳,您可以使用它直接连接到WSDL并执行所需的操作。因此,在您的程序中,您只需要这个和相应的代码,并为WSDL提供参数并执行所需的方法,而无需从WSDL导入任何类。 - Maciej Cygan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接