如何从 Java 类调用 SOAP Web 服务? [英] How to do a SOAP Web Service call from Java class?

查看:35
本文介绍了如何从 Java 类调用 SOAP Web 服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对网络服务世界还比较陌生,我的研究似乎让我困惑而不是启发我,我的问题是我得到了一个库(jar),我必须用一些网络服务功能扩展它.

I'm relative new to the webservices world and my research seems to have confused me more than enlighten me, my problem is that I was given a library(jar) which I have to extend with some webservice functionality.

这个库将共享给其他开发人员,jar 中的类将具有调用 web 服务的方法的类(本质上设置类的属性,执行一些业务逻辑,例如将对象存储在db 等,并发送回带有这些修改的对象).我想让对这个服务的调用尽可能简单,希望尽可能简单,以便使用该类的开发人员只需要做.

This library will be shared to other developers, and among the classes in the jar will be classes that have a method which calls a webservice (that essentially sets an attribute of the class, does some business logic, like storing the object in a db, etc and sends back the object with those modifications). I want to make the call to this service as simple as possible, hopefully as simple so that the developer using the class only need to do.

Car c = new Car("Blue");
c.webmethod();

我一直在研究要在服务器上使用的 JAX-WS,但在我看来,我不需要在服务器中创建 wsimport,也不需要在服务器上创建 wsimport客户端,因为我知道两者都有类,所以我只需要在服务器和客户端共享的类之间进行一些交互.你认为如何在课堂上做网络服务和调用有意义?

I have been studying JAX-WS to use on the server but seems to me that I don't need to create a wsimport in the server nor the wsimport on the client, since I know that both have the classes, I just need some interaction between classes shared in both the server and the client. How do you think makes sense to do the webservice and the call in the class?

推荐答案

我了解您的问题归结为如何从 Java 调用 SOAP (JAX-WS) Web 服务并获取其返回对象.在这种情况下,您有两种可能的方法:

I understand your problem boils down to how to call a SOAP (JAX-WS) web service from Java and get its returning object. In that case, you have two possible approaches:

  1. 通过wsimport生成Java类并使用;或
  2. 创建一个 SOAP 客户端,该客户端:
  1. Generate the Java classes through wsimport and use them; or
  2. Create a SOAP client that:
  1. 将服务的参数序列化为 XML;
  2. 通过HTTP操作调用web方法;和
  3. 将返回的 XML 响应解析回一个对象.


关于第一种方法(使用wsimport):


About the first approach (using wsimport):

我看到您已经拥有服务的(实体或其他)业务类,事实上 wsimport 生成了一组全新的类(这些类在某种程度上与您已有的类重复)有).

I see you already have the services' (entities or other) business classes, and it's a fact that the wsimport generates a whole new set of classes (that are somehow duplicates of the classes you already have).

不过,恐怕在这种情况下,您只能:

I'm afraid, though, in this scenario, you can only either:

  • 改编(编辑)wsimport 生成的代码以使其使用您的 业务类(这很困难,而且不知何故不值得 - 每次 WSDL 更改时请记住,您必须重新生成并重新调整代码);或
  • 放弃并使用 wsimport 生成的类.(在此解决方案中,您的业务代码可以使用"生成的类作为来自另一个架构层的服务.)
  • Adapt (edit) the wsimport generated code to make it use your business classes (this is difficult and somehow not worth it - bear in mind everytime the WSDL changes, you'll have to regenerate and readapt the code); or
  • Give up and use the wsimport generated classes. (In this solution, you business code could "use" the generated classes as a service from another architectural layer.)

关于第二种方法(创建您的自定义 SOAP 客户端):

为了实施第二种方法,您必须:

In order to implement the second approach, you'll have to:

  1. 拨打电话:
    • 使用 SAAJ(SOAP with Attachments API for Java)框架(见下文,Java SE 1.6 或更高版本随附)进行调用;或
    • 您也可以通过 java.net.HttpUrlconnection(以及一些 java.io 处理)来实现.
  1. Make the call:
    • Use the SAAJ (SOAP with Attachments API for Java) framework (see below, it's shipped with Java SE 1.6 or above) to make the calls; or
    • You can also do it through java.net.HttpUrlconnection (and some java.io handling).
  • 使用 OXM(对象到 XML 映射)框架(例如 JAXB)从/向对象序列化/反序列化 XML
  • 或者,如果必须,手动创建/解析 XML(如果收到的对象与发送的对象只有一点点不同,这可能是最佳解决方案).

使用经典的 java.net.HttpUrlConnection 创建 SOAP 客户端并没有那么难(但也没有那么简单),您可以在 这个链接 一个非常好的起始代码.

Creating a SOAP client using classic java.net.HttpUrlConnection is not that hard (but not that simple either), and you can find in this link a very good starting code.

我建议您使用 SAAJ 框架:

I recommend you use the SAAJ framework:

SOAP with Attachments API for Java (SAAJ) 主要用于直接处理发生在任何 Web 服务 API 的幕后的 SOAP 请求/响应消息.它允许开发人员直接发送和接收soap消息,而不是使用JAX-WS.

SOAP with Attachments API for Java (SAAJ) is mainly used for dealing directly with SOAP Request/Response messages which happens behind the scenes in any Web Service API. It allows the developers to directly send and receive soap messages instead of using JAX-WS.

请参阅下面的使用 SAAJ 的 SOAP Web 服务调用的工作示例(运行它!).它调用此网络服务.

See below a working example (run it!) of a SOAP web service call using SAAJ. It calls this web service.

import javax.xml.soap.*;

public class SOAPClientSAAJ {

    // SAAJ - SOAP Client Testing
    public static void main(String args[]) {
        /*
            The example below requests from the Web Service at:
             https://www.w3schools.com/xml/tempconvert.asmx?op=CelsiusToFahrenheit


            To call other WS, change the parameters below, which are:
             - the SOAP Endpoint URL (that is, where the service is responding from)
             - the SOAP Action

            Also change the contents of the method createSoapEnvelope() in this class. It constructs
             the inner part of the SOAP envelope that is actually sent.
         */
        String soapEndpointUrl = "https://www.w3schools.com/xml/tempconvert.asmx";
        String soapAction = "https://www.w3schools.com/xml/CelsiusToFahrenheit";

        callSoapWebService(soapEndpointUrl, soapAction);
    }

    private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
        SOAPPart soapPart = soapMessage.getSOAPPart();

        String myNamespace = "myNamespace";
        String myNamespaceURI = "https://www.w3schools.com/xml/";

        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);

            /*
            Constructed SOAP Request Message:
            <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="https://www.w3schools.com/xml/">
                <SOAP-ENV:Header/>
                <SOAP-ENV:Body>
                    <myNamespace:CelsiusToFahrenheit>
                        <myNamespace:Celsius>100</myNamespace:Celsius>
                    </myNamespace:CelsiusToFahrenheit>
                </SOAP-ENV:Body>
            </SOAP-ENV:Envelope>
            */

        // SOAP Body
        SOAPBody soapBody = envelope.getBody();
        SOAPElement soapBodyElem = soapBody.addChildElement("CelsiusToFahrenheit", myNamespace);
        SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Celsius", myNamespace);
        soapBodyElem1.addTextNode("100");
    }

    private static void callSoapWebService(String soapEndpointUrl, String soapAction) {
        try {
            // Create SOAP Connection
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();

            // Send SOAP Message to SOAP Server
            SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl);

            // Print the SOAP Response
            System.out.println("Response SOAP Message:");
            soapResponse.writeTo(System.out);
            System.out.println();

            soapConnection.close();
        } catch (Exception e) {
            System.err.println("
Error occurred while sending SOAP Request to Server!
Make sure you have the correct endpoint URL and SOAPAction!
");
            e.printStackTrace();
        }
    }

    private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();

        createSoapEnvelope(soapMessage);

        MimeHeaders headers = soapMessage.getMimeHeaders();
        headers.addHeader("SOAPAction", soapAction);

        soapMessage.saveChanges();

        /* Print the request message, just for debugging purposes */
        System.out.println("Request SOAP Message:");
        soapMessage.writeTo(System.out);
        System.out.println("
");

        return soapMessage;
    }

}

关于使用 JAXB 进行序列化/反序列化,很容易找到相关信息.你可以从这里开始:http://www.mkyong.com/java/jaxb-hello-world-example/.

About using JAXB for serializing/deserializing, it is very easy to find information about it. You can start here: http://www.mkyong.com/java/jaxb-hello-world-example/.

这篇关于如何从 Java 类调用 SOAP Web 服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆