springboot+cxf框架使用WebService
WebService简介
Web Service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。
有点官方了,其实说白了,就是远程调用别人写好的服务
假如我要调用天气服务,天气预报系统就相当于webservice的服务端,我们的系统就相当于客户端,直接调用天气预报的服务就可
那么如何调用呢
要获取webservice的 wsdl 文档:通过在webservice的url后面加?wsdl的方式
假如调用天气预报服务:
http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
文档解读
wsdl 文档 解析
Wsdl文档从下往上读
Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。(入参和出参的数据类型)
Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构(入参和出参)。
Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对(方法)。
PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持(服务类)。
Binding - 特定服务访问点与具体服务类的绑定(不看内容,看关系)。
Port - 定义为webservice单个服务访问点。
Service- 相关服务访问点的集合。
WebService的主流框架
AXIS
XFire
CXF
我们这里用的是cxf框架
开始写我们的项目
首先是服务端:
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.6</version>
</dependency>
service接口
@WebService(name = "DemoService", targetNamespace = "http://service.wlh.com/")
public interface DemoService {
String sayHello(String msg);
}
// @WebService
name : 服务名
targetNamespace : 目标命名空间 注意: http://service.wlh.com/ 不要少了 "/"
Service接口实现类
@WebService(name = "DemoService", targetNamespace = "http://service.wlh.com/", endpointInterface = "com.wlh.service.DemoService")
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String msg) {
return msg+",现在时间:"+"("+new Date()+")";
}
}
// @WebService
name : 服务名
targetNamespace : 目标命名空间 注意: http://service.wlh.com/ 不要少了 "/"
endpointInterface : 指定服务类
CXF配置类
@Configuration
public class CxfConfig {
@Bean
public ServletRegistrationBean dispatcherServletAdr(){
return new ServletRegistrationBean(new CXFServlet(),"/demo/*");
}
// demo目录
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus(){
return new SpringBus();
}
@Bean
public DemoService demoService(){
return new DemoServiceImpl();
}
@Bean
public Endpoint endpoint1(){
Endpoint endpoint = new EndpointImpl(springBus(), statusService());
endpoint.publish("/api");
return endpoint;
}
@Bean
public Endpoint endpoint2(){
Endpoint endpoint = new EndpointImpl(springBus(), demoService());
endpoint.publish("/api2");
return endpoint;
}
// 可以 发布 多个 WebService
// 要注意: endpoint.publish(); 路径 不要 相同。。
}
声明后,启动项目,我们就可以http://ip:port/demo/api?wsdl访问
我们使用浏览器看下这个服务的wsdl文档
访问时会看到类似于这样的xml文档
客户端相对来说就比较简单了,直接调用就可以了
引入依赖:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.11</version>
</dependency>
调用,我这里就写一个入口类调用吧,动态代理模式
public static void invokeRemoteService() throws Exception{
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
// http://localhost:8080/demo/api?wsdl 是我们要访问的服务地址
Client client = dcf.createClient("http://localhost:8080/demo/api?wsdl");
// invoke方法中sayHello 是方法名,后面参数
Object[] objects = client.invoke("sayHello", "hello world");
System.out.println("返回数据:" + JSON.toJSONString(objects[0]));
}
返回值会返回到Object[] 中,后面根据项目需求处理数据。。