# 一、webservice概述
# 1.1 目标
了解webservice应用场景,并理解webservice中常用两种规范的区别
# 1.2 详解
什么是webservice ?
Web Services 属于 RPC 的一种。Web Services 使用 SOAP 作为传输协议,使用 WSDL 作为服务的描述语言,使用 UDDI 作为服务注册发现(虽然没有发展起来)。虽然 Web Services 的相关协议在 2007 年之后基本就没再更新,但是在一些银行等金融机构,Web Services 还在被大量使用。WebService 的框架很多,比如 Axis2,XFire,CXF 等等。Apache Cxf 是其中最优秀,最具有生命力的一个,而且 CXF 框架不仅仅是一个 Web Services 框架,甚至可以通过 CXF 来实现 RESTful 风格的服务。
soap协议
简单对象访问协议(Simple Object Access Protocol,SOAP)是一种基于 XML 的协议,可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME),基于“通用”传输协议是 SOAP的一个优点。
webservice三种规范
JAXM&SAAJ 规范 已废弃
JAX-WS 【了解】
全称是JavaTM API for XML-Based Web Services
SOAP: 基于 HTTP 协议,采用 XML 格式,用来传递信息的格式。 MIMETYPEresponse.setContentType()
WSDL: 用来描述如何访问具体的服务。
它是服务提供者对外公开,服务调用者就可以通过jdk提供wsimport工具对wsdl解析生成代码
UDDI: 用户自己可以按 UDDI 标准搭建 UDDI 服务器,用来管理,分发,查询 WebService 。
其他用户可以自己注册发布 WebService 调用。
JAX-RS 【重点】
- 全称是JavaTM API for RESTful Web Services
- restful
- restful 通过一条url就可以完成crud http://localhost:8888/user 添加 POST 修改 PUT 查询 GET 删除 DELETE
- 可以xml或json来进行数据交换
- CXF
- 我们在调用服务时,可以直接使用WebClient.create(url).访问方式(param);
# 1.3 小结
可以使用webservice来完成不同系统之间调用,数据传输一般使用xml或json。
webservice有两种常用规范,JAX-WS JAX-RS
# 二、SpringBoot整合WebServices(基于JAX-WS)
# 2.1 目标
了解基于jax-ws的服务发布与调用
# 2.2服务发布详解
# 2.2.1 创建SpringBoot项目并添加jaxws依赖
<!-- webservice cxf -->
<!-- jaxws规范 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.5.3</version>
</dependency>
如果发布失败,注意版本差距不能太大
https://mvnrepository.com/artifact/org.apache.cxf/cxf-spring-boot-starter-jaxws/3.5.3

# 2.2.2 创建接口
WebServiceDemo
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService(name = "WebServiceDemo", targetNamespace = "https://www.baidu.com")
public interface WebServiceDemo {
@WebMethod
String emrService(@WebParam String data);
}
# 2.2.3创建实现类
注:目标命名空间必须与接口一致
WebServiceDemoImpl
import org.springframework.stereotype.Component;
import javax.jws.WebService;
@Component
@WebService(name = "WebServiceDemo", //服务名
targetNamespace = "https://www.baidu.com", //包名倒叙,并且和接口定义保持一致
endpointInterface = "com.baidu.www.app.service.WebServiceDemo") // 接口所在的位置
public class WebServiceDemoImpl implements WebServiceDemo{
@Override
public String emrService(String data) {
if (null == data || "".equals(data.trim())) {
return "传入的参数为空";
}
return "调用成功,传入的参数是:" + data;
}
}
# 2.2.4 创建配置类
注册服务,暴露服务调用地址
WebServiceConfig
import com.geekdive.test.app.service.WebServiceDemo;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class WebServiceConfig {
@Autowired
private WebServiceDemo webServiceDemo;
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), webServiceDemo);
//设置接口地址
endpoint.publish("/ws/api");
return endpoint;
}
}
# 2.2.5 启动项目
服务发布成功访问http://localhost:8080/services/ws/api?wsdl可以看到如图所示的页面

# 2.3 服务调用详解
# 2.3.1 使用idea生成客户端
1、新建client包存放生成的文件,在项目根目录。按两下shift,然后搜索webService,选择webService来打开窗口。
2、选择第一项,在窗口中设置wsdl路径,输出路径选择你要把生成的代码放到哪里,然后点确定
3、成功生成客户端文件
# 2.3.2 使用main函数测试(代理类工厂的方式)
代理类工厂的方式,需要拿到对方的接口
public static void main(String[] args) {
String address = "http://127.0.0.1:8080/services/ws/api?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(WebServiceDemo.class);
// 创建一个代理接口实现
WebServiceDemo cs = (WebServiceDemo) jaxWsProxyFactoryBean.create();
// 数据准备
String data = String.valueOf(new Date());
// 调用代理接口的方法调用并返回结果
String rs = cs.emrService(data);
System.out.println("==============\n返回结果:" + rs);
}
# 控制台输出效果

# 2.3.3 使用main函数测试(动态调用方式)
动态调用方式,优点:动态客户端调用,利用反射不需要引入服务端Service类
public static void main(String[] args) {
//创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
try {
Client client = dcf.createClient("http://127.0.0.1:8080/services/ws/api?wsdl");
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
Object[] objects = new Object[0];
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("emrService", "" + new Date());
System.out.println("返回数据:" + objects[0]);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
控制台输出效果

# 2.4 soapUI测试
# 2.4.1用soapUI导入wsdl文件发送交易报文
1.初始soapUI工作窗口
2.右击Project-》点击New SOAP Project打开新建窗口

3.点击 Browse... 按钮找到wsdl文件路径,选中,导入即可,点击OK完成创建

4.创建完成出现一下工作窗口
5.点击你需要测试的接口,双击Request1,输入对应的参数。
6.点击绿色按钮开始发送数据测试。
