杰瑞科技汇

java webservice 动态调用

Java WebService 动态调用指南

在Java中动态调用WebService有多种方法,以下是几种常用的实现方式:

使用JAX-WS动态调用

基于Dispatch API

import javax.xml.namespace.QName;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.net.URL;
public class DynamicWebServiceClient {
    public static void main(String[] args) throws Exception {
        // WebService的WSDL地址
        String wsdlUrl = "http://example.com/service?wsdl";
        // 命名空间
        String namespaceUri = "http://example.com/service";
        // 服务名
        String serviceName = "MyService";
        // 端点名
        String portName = "MyPort";
        // 创建Service实例
        URL url = new URL(wsdlUrl);
        QName qname = new QName(namespaceUri, serviceName);
        Service service = Service.create(url, qname);
        // 创建Dispatch实例
        QName portQname = new QName(namespaceUri, portName);
        Dispatch<StreamSource> dispatch = service.createDispatch(portQname, StreamSource.class, Service.Mode.PAYLOAD);
        // 准备SOAP请求
        String soapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                             "<soapenv:Header/>" +
                             "<soapenv:Body>" +
                             "<ns1:myOperation xmlns:ns1=\"http://example.com/service\">" +
                             "<param1>value1</param1>" +
                             "<param2>value2</param2>" +
                             "</ns1:myOperation>" +
                             "</soapenv:Body>" +
                             "</soapenv:Envelope>";
        // 发送请求并获取响应
        StreamSource response = dispatch.invoke(new StreamSource(new StringReader(soapRequest)));
        // 处理响应
        // ...
    }
}

使用Apache CXF动态调用

添加依赖

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>3.4.0</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>3.4.0</version>
</dependency>

动态调用代码

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.JaxWsDynamicClientFactory;
public class CxfDynamicClient {
    public static void main(String[] args) {
        // 方法1:使用JaxWsProxyFactoryBean(需要知道接口)
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(MyService.class);
        factory.setAddress("http://example.com/service");
        MyService service = (MyService) factory.create();
        // 调用方法
        String result = service.myOperation("param1", "param2");
        System.out.println(result);
        // 方法2:使用JaxWsDynamicClientFactory(完全动态)
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://example.com/service?wsdl");
        // 调用方法
        Object[] res = client.invoke("myOperation", "param1", "param2");
        System.out.println(res[0]);
    }
}

使用Spring-WS动态调用

添加依赖

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-core</artifactId>
    <version>3.1.0</version>
</dependency>

动态调用代码

import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
public class SpringWsDynamicClient {
    public static void main(String[] args) {
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        webServiceTemplate.setMessageFactory(new SaajSoapMessageFactory());
        // 准备SOAP请求
        String soapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                             "<soapenv:Header/>" +
                             "<soapenv:Body>" +
                             "<ns1:myOperation xmlns:ns1=\"http://example.com/service\">" +
                             "<param1>value1</param1>" +
                             "<param2>value2</param2>" +
                             "</ns1:myOperation>" +
                             "</soapenv:Body>" +
                             "</soapenv:Envelope>";
        // 发送请求
        String response = (String) webServiceTemplate.marshalSendAndReceive(
            "http://example.com/service", 
            new StringSource(soapRequest)
        );
        System.out.println(response);
    }
}

使用第三方库(如WebService-Client)

import com.sun.xml.ws.client.ClientTransportException;
import com.sun.xml.ws.api.message.Message;
import com.sun.xml.ws.api.message.Messages;
import com.sun.xml.ws.client.dispatch.DispatchImpl;
import com.sun.xml.ws.client.sei.SEIStub;
public class WebServiceClient {
    public static void main(String[] args) {
        try {
            // 创建动态调用实例
            DispatchImpl dispatch = new DispatchImpl(
                null, // BindingProvider
                null, // Service
                null, // Port
                null, // DataBinding
                Message.EMPTY
            );
            // 设置目标地址
            dispatch.setEndpointAddress("http://example.com/service");
            // 准备SOAP请求
            String soapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                                 "<soapenv:Header/>" +
                                 "<soapenv:Body>" +
                                 "<ns1:myOperation xmlns:ns1=\"http://example.com/service\">" +
                                 "<param1>value1</param1>" +
                                 "<param2>value2</param2>" +
                                 "</ns1:myOperation>" +
                                 "</soapenv:Body>" +
                                 "</soapenv:Envelope>";
            // 发送请求
            Message response = dispatch.invoke(Messages.create(soapRequest));
            // 处理响应
            String result = readResponse(response);
            System.out.println(result);
        } catch (ClientTransportException e) {
            e.printStackTrace();
        }
    }
}

注意事项

  1. 安全性:动态调用时确保使用HTTPS,并考虑添加认证信息
  2. 性能:频繁创建WebService客户端会影响性能,考虑重用客户端实例
  3. 错误处理:添加适当的异常处理机制
  4. WSDL解析:动态调用通常需要解析WSDL,确保WSDL地址可访问
  5. SOAP版本:确保客户端和服务器使用相同的SOAP版本(1.1或1.2)

选择哪种方法取决于你的具体需求,如果你有现成的服务接口,可以使用JAX-WS或CXF的代理方式;如果需要完全动态的调用,则可以使用Dispatch API或CXF的动态客户端工厂。

分享:
扫描分享到社交APP
上一篇
下一篇