目录
why WebService ?
目前的服务直接的接口调用一般很少采用webservice方式了,一般采用resful方式或消息队列等技术,主要是一些遗留的老项目需要对接,而老项目又只有提供webservice方式可以对接,所以不得不去了解一下webservice技术。
what is WebService ?
本质上它是一个为了实现不同开发语言之前的接口调用服务的一个治理框架。
可查看网上一些不错的介绍文章
https://www.jianshu.com/p/5bb727b434e6
how to use WebService ?
以java语言为例:
- 原生方式
- cxf方式
- axis方式
具体技术介绍可查看如下不错的总结文章:
https://blog.csdn.net/linjinhuo/article/details/78777694
cxf for springboot
这里我们采用cxf为例做一个简单介绍。
建议查看apache cxf官网介绍: http://cxf.apache.org/docs/springboot.html
1. 引入依赖
pom.xml文件引入如下内容,注意版本和springboot 的版本兼容
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.3.7</version>
</dependency>
2. 配置访问wsdl路径前缀
application.yml文件引入如下内容, webservice的wsdl访问路径的前缀,可以任意定义
cxf:
path: /soap
3. 创建服务接口
package com.middol.mytest.webservice;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
/**
* @author 哈士奇大D
* 这里面不要定义 serviceName name 或 endpointInterface 属性 !!!
*/
@WebService(
targetNamespace = "http://webservice.mytest.middol.com")
public interface WebServiceDemoService {
/**
* hello
*
* @param name name
* @return str
*/
@WebMethod(operationName = "sayHello")
@WebResult(name = "result")
String sayHello(@WebParam(name = "yourName",targetNamespace = "http://webservice.mytest.middol.com") String yourName);
/**
* hello
*
* @param name name
* @return str
*/
@WebMethod(operationName = "sayBye")
@WebResult(name = "result")
String sayBye(@WebParam(name = "myName",targetNamespace = "http://webservice.mytest.middol.com") String myName);
}
4. 创建接口实现类
package com.middol.mytest.webservice.impl;
import com.middol.mytest.webservice.WebServiceDemoService;
import org.springframework.stereotype.Service;
import javax.jws.WebService;
/**
* @author 哈士奇大D
*/
@Service
@WebService(
serviceName = "webServiceDemoService", // 发布的服务名
targetNamespace = "http://webservice.mytest.middol.com", // 与接口中的命名空间一致,一般是接口的包名倒
endpointInterface = "com.middol.mytest.webservice.WebServiceDemoService" // 接口地址
)
public class WebServiceDemoServiceImpl implements WebServiceDemoService {
@Override
public String sayHello(String name) {
return "hello ! " + name;
}
@Override
public String sayBye(String name) {
return "Bye ! " + name;
}
}
5. 创建config配置类
主要是注册发布webservice接口服务
package com.middol.mytest.config.webservice;
import com.middol.mytest.webservice.WebServiceDemoService;
import org.apache.cxf.Bus;
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.annotation.Resource;
import javax.xml.ws.Endpoint;
/**
* @author 哈士奇大D
*/
@Configuration
public class WebServiceConfig {
@Resource(name = "webServiceDemoServiceImpl")
private WebServiceDemoService webServiceDemoService;
@Autowired
private Bus bus;
/**
* 注册WebServiceDemoService接口到webservice服务
*
* @return Endpoint
*/
@Bean(name = "webServiceDemoEndpoint")
public Endpoint webServiceDemoEndpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, webServiceDemoService);
endpoint.publish("/myHello");
return endpoint;
}
}
6. 启动springboot 服务
可查看控制台日志有如下输出:
2020-07-29 11:00:17.039 INFO 11932 --- [ main] o.a.c.w.s.f.ReflectionServiceFactoryBean : Creating Service {http://webservice.mytest.middol.com}webServiceDemoService from class com.middol.mytest.webservice.WebServiceDemoService
2020-07-29 11:00:17.566 INFO 11932 --- [ main] org.apache.cxf.endpoint.ServerImpl : Setting the server's publish address to be /myHello
访问 webservice 服务发布的 wsdl路径:
http://xxxxxx/soap/myHello?wsdl
xxxxxx为你的springboot 应用路径.例如:http://localhost:8081/mytest/
7. 客户端测试
方法一:采用cxf方式
方法二:采用hutools SoapClient方式
hutools SoapClient 介绍请查看:https://www.hutool.cn/docs/#/http/WebService/Soap%E5%AE%A2%E6%88%B7%E7%AB%AF-SoapClient
package com.test.xml;
import cn.hutool.http.webservice.SoapClient;
import cn.hutool.http.webservice.SoapProtocol;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class WebServiceClientTest {
// 方法一
public static void jaxWsDynamicTest() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:8081/mytest/soap/myHello?wsdl");
Object[] objects;
try {
objects = client.invoke("sayHello", "武云");
System.out.println("返回数据:" + objects[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
// 方法二
public static void hutoolsTest() {
SoapClient soapClient = SoapClient.create("http://localhost:8081/mytest/soap/myHello?wsdl", SoapProtocol.SOAP_1_1, "http://webservice.mytest.middol.com");
// 这里说一下为什么方法名称要加一个 web: ,这个请用 SoapUI 客户端解析一下wsdl,可创建一个request
// 这时可查看 request请求内容里面的xml具体内容,可看到有web: 这个命名空间的前缀
/**
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.mytest.middol.com">
<soapenv:Header/>
<soapenv:Body>
<web:sayHello>
<!--Optional:-->
<web:yourName>?</web:yourName>
</web:sayHello>
</soapenv:Body>
</soapenv:Envelope>
**/
String soapMessage = soapClient.
setMethod("web:sayBye").setParam("myName", "张良").send(true);
System.out.println(soapMessage);
}
public static void main(String[] args) {
// 采用cxf方式
jaxWsDynamicTest();
// 采用hutools SoapClient
hutoolsTest();
}
}