【问题标题】:How to consume a SOAP web service in Java如何在 Java 中使用 SOAP Web 服务
【发布时间】:2013-09-23 01:30:06
【问题描述】:

谁能帮我提供一些关于如何在 Java 中使用 Web 服务 WSDL 的链接和其他内容?

【问题讨论】:

标签: java xml jakarta-ee soap


【解决方案1】:

有许多选项可以使用基于 WSDL 创建的 Stub 或 Java 类来使用 SOAP Web 服务。但如果有人想在不创建任何 Java 类的情况下执行此操作,this 文章非常有帮助。 文章中的代码片段:

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 时正在寻找类似的文件上传解决方案的人,请参阅这篇文章:How to attach a file (pdf, jpg, etc) in a SOAP POST request?

【讨论】:

    【解决方案2】:

    我会使用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.
    

    【讨论】:

    • 我觉得我的工作压力很大。如果导入 WSDL 文件决定了您是生是死,那么您一定是把它弄坏了。大声笑
    【解决方案3】:

    正如一些人建议的那样,您可以使用 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,它就会创建许多看起来非常复杂的类。我可以使用一种简单的技术吗?
    • @user755611 我向您展示的代码不会导入任何类。它是一个动态客户端的外壳,您可以使用它直接连接到 wsdl 并执行您想要的操作。因此,在您的程序中,您将只有这个和相应的代码,并为 wsdl 提供参数并执行所需的方法,而无需从 wsdl 导入任何类
    【解决方案4】:

    Here 您可以找到一个很好的教程,介绍如何通过 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
    

    创建存根后,您可以非常简单地调用 Web 服务,例如:

    TestHarnessService harnessService = new TestHarnessService();
    ITestApi testApi = harnessService.getBasicHttpBindingITestApi();
    testApi.resetLogMemoryTarget();
    

    【讨论】:

      猜你喜欢
      • 2012-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多