Spring Boot调用SOAP Web Service
Spring Boot项目中,调用遗留的SOAP Web Service,方法很简单,仅需引入spring-boot-starter-web-services。
org.springframework.boot spring-boot-starter-web-services
WebServiceTemplate
我们使用WebServiceTemplate来调用SOAP Service。WebServiceTemplate提供了三类调用方法sendSourceAndReceive、marshalSendAndReceive、sendAndReceive。sendSourceAndReceive方法直接发送和接收XML message;marshalSendAndReceive方法发送、接收结果则为对象,由配置的Marshaller和Unmarshaller自动转换;sendAndReceive支持更底层的操作。
package org.iata.caims.service.ws;import org.springframework.boot.webservices.client.WebServiceTemplateBuilder;import org.springframework.stereotype.Service;import org.springframework.ws.client.core.WebServiceTemplate;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;import java.io.StringReader;@Servicepublic class MyService { private static final String DEFAULT_URI = "http://localhost:8080/HelloService"; private static final String MESSAGE = "" + "\n" + " COCO \n" + " "; private final WebServiceTemplate webServiceTemplate; public MyService(WebServiceTemplateBuilder webServiceTemplateBuilder) { this.webServiceTemplate = webServiceTemplateBuilder.setDefaultUri(DEFAULT_URI).build(); } public void sendSourceAndReceive() { StreamSource source = new StreamSource(new StringReader(MESSAGE)); StreamResult result = new StreamResult(System.out); webServiceTemplate.sendSourceAndReceiveToResult(source, result); } public Object marshalSendAndReceive(String uri, Object requestPayload) { return this.webServiceTemplate.marshalSendAndReceive(uri, requestPayload); }}
marshalSendAndReceive是常用的方法。您可以通过阅读wsdl文件来了解Web Service支持的方法和参数,也可以使用SoapUI工具生成request、response XML,然后手工编写SOAP Domain对象。更简单的方法是使用maven-jaxb2-plugin插件自动生成。
maven-jaxb2-plugin
org.jvnet.jaxb2.maven2 maven-jaxb2-plugin 0.14.0 generate org.itrunner.ws ${project.basedir}/src/main/java ${project.basedir}/src/main/resources/wsdl *.wsdl
如上配置,将wsdl文件放入resources/wsdl文件夹,maven编译时将在指定包生成所有Web Service方法相关的stub类,其中包括package-info.java、ObjectFactory、request、response,并已配置好XML注解。
package-info.java
@javax.xml.bind.annotation.XmlSchema(namespace = "http://webservice.itrunner.org", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)package org.iata.caims.service.test;
ObjectFactory
import javax.xml.bind.annotation.XmlRegistry;@XmlRegistrypublic class ObjectFactory { /** * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.itrunner.ws */ public ObjectFactory() { } /** * Create an instance of {@link SayHello } */ public SayHello createSayHello() { return new SayHello(); } /** * Create an instance of {@link SayHelloResponse } */ public SayHelloResponse createSayHelloResponse() { return new SayHelloResponse(); }}
Request
Request类名对应Web Service方法名,属性对应Web Service参数。
import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.XmlType;@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "", propOrder = { "in0"})@XmlRootElement(name = "sayHello")public class SayHello { @XmlElement(required = true, nillable = true) protected String in0; /** * Gets the value of the in0 property. * * @return possible object is {@link String } */ public String getIn0() { return in0; } /** * Sets the value of the in0 property. * * @param value allowed object is {@link String } */ public void setIn0(String value) { this.in0 = value; }}
Response
import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.XmlType;@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "", propOrder = { "out"})@XmlRootElement(name = "sayHelloResponse")public class SayHelloResponse { @XmlElement(required = true, nillable = true) protected String out; /** * Gets the value of the out property. * * @return possible object is {@link String } */ public String getOut() { return out; } /** * Sets the value of the out property. * * @param value allowed object is {@link String } */ public void setOut(String value) { this.out = value; }}
牛刀小试
配置WebServiceTemplateBuilde与Jaxb2Marshaller:
import org.springframework.boot.webservices.client.HttpWebServiceMessageSenderBuilder;import org.springframework.boot.webservices.client.WebServiceTemplateBuilder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.oxm.jaxb.Jaxb2Marshaller;import org.springframework.ws.client.core.WebServiceTemplate;import static java.time.Duration.ofSeconds;@Configurationpublic class Config { @Bean public WebServiceTemplate webServiceTemplate(WebServiceTemplateBuilder builder) { return builder.messageSenders(new HttpWebServiceMessageSenderBuilder().setConnectTimeout(ofSeconds(60)).setReadTimeout(ofSeconds(60)).build()).build(); } @Bean public Jaxb2Marshaller jaxb2Marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setContextPath("org.itrunner.ws"); return marshaller; }}
调用Web Service:
import org.springframework.boot.webservices.client.WebServiceTemplateBuilder;import org.springframework.oxm.jaxb.Jaxb2Marshaller;import org.springframework.stereotype.Service;import org.springframework.ws.client.core.WebServiceTemplate;@Servicepublic class HelloService { private static final String DEFAULT_URI = "http://localhost:8080/HelloService"; private final WebServiceTemplate webServiceTemplate; public HelloService(WebServiceTemplateBuilder webServiceTemplateBuilder, Jaxb2Marshaller jaxb2Marshaller) { this.webServiceTemplate = webServiceTemplateBuilder.setDefaultUri(DEFAULT_URI) .setMarshaller(jaxb2Marshaller).setUnmarshaller(jaxb2Marshaller).build(); } public SayHelloResponse sayHello(SayHello request) { return (SayHelloResponse) this.webServiceTemplate.marshalSendAndReceive(request); }}
参考文档
Spring Boot Reference Guide
Spring Boot SOAP Client - WebServiceTemplate Example