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();
}
}
}
注意事项
- 安全性:动态调用时确保使用HTTPS,并考虑添加认证信息
- 性能:频繁创建WebService客户端会影响性能,考虑重用客户端实例
- 错误处理:添加适当的异常处理机制
- WSDL解析:动态调用通常需要解析WSDL,确保WSDL地址可访问
- SOAP版本:确保客户端和服务器使用相同的SOAP版本(1.1或1.2)
选择哪种方法取决于你的具体需求,如果你有现成的服务接口,可以使用JAX-WS或CXF的代理方式;如果需要完全动态的调用,则可以使用Dispatch API或CXF的动态客户端工厂。
