此笔记为利用Spring WS的WS-Addressing发送SOAP请求及接收其响应。
WS-Addressing(Web服务寻址):传送Web服务端点的引用的数据结构,以及一套能够在特定的消息上关联寻址信息的消息寻址属性。
服务端
@Endpoint:此注解告诉Spring注解这是个类有资格处理soap请求。
@Action:此注解映射特定的soap行为,比如返回一个简单的POJO类。
package cn.it1995.server;
import cn.it1995.GetTestRequest;
import cn.it1995.GetTestResponse;
import cn.it1995.MyTest;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.ws.soap.addressing.server.annotation.Action;
@Endpoint
public class IT1995Endpoint {
@Action("http://it1995.cn/getTestRequest")
public @ResponsePayload
GetTestResponse getTest(@RequestPayload GetTestRequest request){
GetTestResponse response = new GetTestResponse();
MyTest myTest = new MyTest();
myTest.setId(request.getId());
myTest.setName("Hello World");
response.setMyTest(myTest);
return response;
}
}
关于空的soapAction
在配置Spring ws中,默认情况下都会生成包含空的soapAction的WSDL。可以覆盖这个映射,设置适当的soapAction属性。
如:
DefaultWsdl11Definition.setSoapActions(soapActions)
方法
package cn.it1995.server;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
import java.util.Properties;
@EnableWs
@Configuration
public class SoapServerConfig {
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext){
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
@Bean(name = "it1995")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema schema){
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("IT1995Port");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTransportUri("http://it1995.cn/webservice");
wsdl11Definition.setSchema(schema);
//为动态生成的wsdl添加soap action
Properties soapActions = new Properties();
soapActions.setProperty("getTest", "http://it1995.cn/getTestRequest");
wsdl11Definition.setSoapActions(soapActions);
return wsdl11Definition;
}
@Bean
public XsdSchema it1995Schema(){
return new SimpleXsdSchema(new ClassPathResource("xsd/MyData.xsd"));
}
}
最后是关于Spring Boot的启动项
package cn.it1995.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RunServer {
public static void main(String[] args){
SpringApplication.run(RunServer.class);
}
}
Spring WS-Addressing客户端
配置客户端其中WS-Addressing开启soap请求。通过扩展WebServiceGateWaySupport创建client。通过WebServiceTemplate发送soap请求。首先创建ActionCallback提供了action url。这个location注册了server方法及WSDL。最后通过WebServiceTemplate发送请求及获取Response。
package cn.it1995.client;
import cn.it1995.GetTestRequest;
import cn.it1995.GetTestResponse;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.soap.addressing.client.ActionCallback;
import java.net.URI;
import java.net.URISyntaxException;
public class IT1995Client extends WebServiceGatewaySupport {
public GetTestResponse getTest(int id) throws URISyntaxException {
GetTestRequest request = new GetTestRequest();
request.setId(id);
ActionCallback callback = new ActionCallback(
new URI("http://it1995.cn/getTestRequest")
);
return (GetTestResponse)getWebServiceTemplate().marshalSendAndReceive(request, callback);
}
}
配置client端,创建一个marshaller发送请求及获取响应,初始化客户端。
package cn.it1995.client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
@Configuration
public class SoapClientConfig {
@Bean
public Jaxb2Marshaller marshaller(){
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("cn.it1995");
return marshaller;
}
@Bean
public IT1995Client it1995Client(Jaxb2Marshaller marshaller){
IT1995Client client = new IT1995Client();
client.setDefaultUri("http://localhost:8080/ws/it1995");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
配置client端,创建一个marshaller发送请求及获取响应,初始化客户端。
package cn.it1995.client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
@Configuration
public class SoapClientConfig {
@Bean
public Jaxb2Marshaller marshaller(){
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("cn.it1995");
return marshaller;
}
@Bean
public IT1995Client it1995Client(Jaxb2Marshaller marshaller){
IT1995Client client = new IT1995Client();
client.setDefaultUri("http://localhost:8080/ws/it1995");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
使用AnnotationConfigApplicationContext初始化客户端,下面是个调用例子:
package cn.it1995.client;
import cn.it1995.GetTestResponse;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.net.URISyntaxException;
public class RunClient {
public static void main(String[] args) throws URISyntaxException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SoapClientConfig.class);
IT1995Client client = context.getBean(IT1995Client.class);
GetTestResponse response = client.getTest(1);
System.out.println(response.getMyTest().getId());
System.out.println(response.getMyTest().getName());
}
}
这里客户端wsdl如下:
源码打包下载地址:
https://github.com/fengfanchen/Java/tree/master/WebServiceAction