WebService
一、定义
WebService也叫XML Web Service,是一种跨编程语言、跨操作系统、跨越终端的远程调用技术,我们把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。
二、WebService三要素
1、SOAP
SOAP 英文全称为:Simple Object Access Protocol,即简单对象访问协议,它是基于 xml 格式的消息交换协议
SOAP协议 = HTTP协议 + XML数据格式
SOAP 定义了信息交换的格式,它包含一个重要的信封 envelope,使用信封envelope 来包装要传递的信息,使用命名空间 namespace 来区分传递的信息;简单来说,在 WebService 中传递的信息就是一封信,SOAP 就是信的通用格式,它定义了一封信应该有信封,信封里装着信的内容.
信封(envlope)的格式是固定的,而信的内容(要传递的数据)可以自己定义;SOAP 协议传输的数据采用 xml 格式进行封装,采用 http 协议进行传输.
2、WSDL
WSDL 英文全称为 Web Service Description Language,即 Web Service 描述语言;它使用 xml 对 Web Service 进行描述,比如提供服务的方法、参数、返回值、数据类型等信息进行描述。
3、UDDI
UDDI (Universal Description, Discovery, and Integration
) 是一个主要针对Web服务供应商和使用者的新项目。在用户能够调用Web服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件。
UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。
三、WebService使用场景
- 应用系统集成
- 异构系统之间通信
- 软件复用
四、WebService结构、调用原理及工作流程
1、结构
- 服务端:提供服务,供客户端调用
- 客户端:调用服务,获取服务数据
2、调用原理
3、工作流程
(1)Web服务提供者设计实现Web服务,并将调试正确后的Web服务通过Web服务中介者发布,并在UDDI注册中心注册;
(2)Web服务请求者向Web服务中介者请求特定的服务,中介者根据请求查询UDDI注册中心,为请求者寻找满足请求的服务;
(3)Web服务中介者向Web服务请求者返回满足条件的Web服务描述信息,该描述信息用WSDL写成,各种支持Web服务的机器都能阅读;
(4)利用从Web服务中介者返回的描述信息生成相应的SOAP消息,发送给Web服务提供者,以实现Web服务的调用;
(5)Web服务提供者按SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者。
五、SpringBoot集成WebService
1、引入相关依赖
本次统一使用3.2.6版本
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.2.6</version>
</dependency>
2、服务端
(1)创建服务端接口
接口使用注解@WebService标注,方法使用@WebMethod标注,方法参数使用@WebParam标注
package com.example.exercise.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService(
name = "UserService",
targetNamespace = "http://service.exercise.example.com"
)
public interface UserService {
@WebMethod
String getInfo(@WebParam(name = "name") String name, @WebParam(name = "age") Integer age);
}
(2)创建服务端接口实现类
package com.example.exercise.service.impl;
import com.example.exercise.service.UserService;
import javax.jws.WebService;
@WebService(
name = "UserService",
targetNamespace = "http://service.exercise.example.com",
endpointInterface = "com.example.exercise.service.UserService"
)
public class UserServiceImpl implements UserService {
@Override
public String getInfo(String name, Integer age) {
String info = "我叫" + name + ",今年" + age + "岁";
return info;
}
}
注意:
- targetNamespace 值为包名反写
- endpointInterface 包名+接口名
(3)创建CXF配置类
package com.example.exercise.config;
import com.example.exercise.service.UserService;
import com.example.exercise.service.impl.UserServiceImpl;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class CxfConfig {
@Bean
public ServletRegistrationBean disServlet() {
return new ServletRegistrationBean(new CXFServlet(),"/user/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public UserService getService(){
return new UserServiceImpl();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), getService());
endpoint.publish("/api");
return endpoint;
}
}
(4)启动SpringBoot项目,访问webservice
http://ip:端口/user/api?wsdl
3.客户端
public static void main(String[] args) {
//创建动态客户端
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
Client client = factory.createClient("http://localhost:8089/user/api?wsdl");
// 需要密码的情况需要加上用户名和密码
//client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(2000); //连接超时
httpClientPolicy.setAllowChunking(false); //取消块编码
httpClientPolicy.setReceiveTimeout(120000); //响应超时
conduit.setClient(httpClientPolicy);
//client.getOutInterceptors().addAll(interceptors);//设置拦截器
try{
// invoke("方法名",参数1,参数2,参数3....);
Object[] objects = client.invoke("getInfo", "张三", 85);
System.out.println("返回数据:" + objects[0]);
}catch (Exception e){
e.printStackTrace();
}
}