webservice 的日常:springboot集成WS
好不容易挤出点时间,来记录一些知识。
webservice上次使用还是三四年前,现在基本都在使用微服务,rest流行,所以webservice大概也只能在老系统或者特定环境下才能用到。
1.springboot集成CXF.
2.webservice的测试.
介绍
webservice是一种可跨语言跨平台的远程调用技术
核心要点:
WSDL
webservice给我们最直观的可见就是WSDL。
wsdl很直观,节点根据名字大概可以知道意思,这里简单说下:
- 正常xs.xsd文件只包含element的xs配置,编译后才会转为对外服务wsdl节点
- xmlns:引入资源
SOAP
是webservice访问协议,通过规范的格式报文调用,或者rest接口请求
UDDI
是webservice依据文档节点对应到服务的一种机制
原理
当我们publish服务后,通过wsdl的url可见注册的方法以及请求返回参数;
然后请求对应的方法后,通过UDDI进行服务对应调度,执行并返回结果。
简单来说:
server发布服务,生成服务注册中心(直观可见wsdl)
client依据wsdl请求,server接到请求处理返回
案例
常用的webservice技术:
axis(现在升级到axis2)、cxf、spring-ws等
如果依赖springboot进行开发, 可以考虑cxf或spring-ws,已经被集成进starter了,也是比较推荐的两种。
spring-ws
如果有提供的wsdl文件,然后进行二次开发,或者使用提供好的wsdl2java的jar,建议使用spring-ws:
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
因为涉及jaxb进行节点绑定,需要引入:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
xsd配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" targetNamespace="http://service.ws.webservice.com"
xmlns:tns="http://service.ws.webservice.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="HelloRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="HelloReq" type="tns:HelloReq"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="HelloResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="HelloResp" type="tns:HelloResp"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="HelloReq">
<xs:sequence>
<xs:element minOccurs="0" name="username" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="HelloResp">
<xs:sequence>
<xs:element minOccurs="0" name="result" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
然后可以通过引入cxf-xjc的依赖进行服务java对象生成,也可以跟直接用命令行生成(两种方式):
xjc *.xsd -p com.huawei.cmas.rse.service
由于会出现中文乱码,建议使用:
java -Dfile.encoding=UTF-8 -cp D:\JAVA\JAVA8\lib\tools.jar com.sun.tools.internal.xjc.Driver -p com.hello.service hello.xsd
然后会生成对应的java对象:
然后配置endpoint暴露接口方法:
@Endpoint
public class WebserviceEndpoint {
private static Logger logger = LoggerFactory.getLogger(WebserviceEndpoint.class);
private static final String NAMESPACE_URI = "http://service.ws.webservice.com";
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "HelloRequest")
@ResponsePayload
public HelloResponse hello(@RequestPayload HelloRequest helloRequest) {
logger.info("helloRequest:{}",
helloRequest.getHelloReq() == null ? null : helloRequest.getHelloReq().getUsername());
HelloResponse response = new HelloResponse();
HelloResp resp = new HelloResp();
resp.setResult(0);
response.setHelloResp(resp);
return new HelloResponse();
}
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "helloNoRequest")
@ResponsePayload
public HelloResponse helloNoRequest() {
logger.info("helloNoRequest!");
HelloResponse response = new HelloResponse();
HelloResp resp = new HelloResp();
resp.setResult(1);
response.setHelloResp(resp);
return new HelloResponse();
}
}
还有wsdl注册等配置:
@EnableWs
@Configuration
public class WebserviceConfig extends WsConfigurerAdapter {
private static final String NAMESPACE_URI = "http://service.ws.webservice.com";
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/hello/*");
}
@Bean(name = "HelloApi")
public Wsdl11Definition defaultWsdl11Definition(XsdSchema rseMockSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("HelloApiPort");
wsdl11Definition.setLocationUri("/hello");
wsdl11Definition.setTargetNamespace(NAMESPACE_URI);
wsdl11Definition.setSchema(rseMockSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema rseMockSchema() {
return new SimpleXsdSchema(new ClassPathResource("xsd/hello.xsd"));
}
@Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
return messageFactory;
}
}
说明:
- @EnableWs 开启ws
- SoapVersion.SOAP_12为soap版本,目前有11和12两个版本,主要差别为12移除了soapAction,测试时用inputsteam这种流模式的socket请求需要12版本。
- 补充:
如果xsd设置了nillxxx=true,会生成JAXBElement类型对象,这时需要使用ObjectFactory来创建对应的参数。
然后浏览器
http://localhost:8080/hello/HelloApi.wsdl
githup:
webservice源码