首先Webservice是干什么的呢?
- 经过学习可以了解到:webservice是可以跨平台,跨开发语言去实现客户端去调用服务端接口,从而达到数据的交换传输。
- 有篇文章有句话总结得很好:抄录自https://www.cnblogs.com/xdp-gacl/p/4048937.html(侵删): WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
- 服务端经过webservice技术把自己的接口暴露出来让有需求的系统得以对接。客户端可以通过账号密码或者某些约定调用服务端的数据。
Webservice有什么内容?:
- XML+XSD,SOAP和WSDL就是构成WebService平台的三大技术:
- XML:负责封装返回的数据,XML的跨平台性使它是这个技术的不二之选。XSD:负责定义数据类型。
- SOAP协议:HTTP协议加XML数据格式。
- WSDL语言:描述服务端的服务,数据类型,返回格式,通过什么URL,什么方式调用。
Webservice适用的场景:
- 企业级应用,当不同平台的系统要相互交换数据,推送数据时,利用Webservice可以实现。
- 例如淘宝等客户群庞大的应用,当外部应用需要对接其中一个接口时,通过Webservice暴露这个接口可以使大量对接需求被满足。
- 等等
Webservice服务端代码实现
pom依赖:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.2.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.2.6</version>
</dependency>
CXF框架使代码在实现调用远程接口的时候更便捷。(需要补充)
接口:
@WebService
public interface HelloWord {
String sayhai(String name);
}
实现接口:
@WebService(targetNamespace="http://WebService.demo.example.com/",endpointInterface = "com.example.demo.WebService.HelloWord")
public class HelloWords implements HelloWord {
@Override
public String sayhai(String name){
return name+"你好,现在北京时间是"+new Date();
}
}
暴露服务:
@Configuration
public class WebServiceConfig {
/*Parameter 1 of constructor in org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration required a bean of type 'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath' that could not be found.
报错----原因是parent版本造成的问题
parent版本是1.4.5,同时jaxws版本是3.1.7时;
parent版本是1.4.5,同时jaxws版本是3.1.11时;
parent版本是1.5.6,同时jaxws版本是3.1.11时;
parent版本是1.5.8,同时jaxws版本是3.1.12时;
parent版本是1.5.9,同时jaxws版本是3.1.11时;
parent版本是1.5.9,同时jaxws版本是3.1.12时;
parent版本是2.0.3,同时jaxws版本是3.2.6时;
则运行正常。
把parent版本改成2.0.3,同时jaxws版本是3.2.6时;
*/
/*http://localhost:8080/service/hello?wsdl访问到接口的xml文档*/
@Bean
public ServletRegistrationBean dispatcherServlet(){
return new ServletRegistrationBean(new CXFServlet(),"/service/*");//发布服务名称
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus()
{
return new SpringBus();
}
@Bean
public HelloWord userService()
{
return new HelloWords();
}
@Bean
public Endpoint endpoint() {
System.out.println("Server is starting...");
EndpointImpl endpoint=new EndpointImpl(springBus(), userService());//绑定要发布的服务
endpoint.publish("/hello"); //显示要发布的名称
System.out.println("Server is stop...");
return endpoint;
}
}
访问wsdl接口文档;
通过SOAPUI工具调用接口测试:
这里填上接口文档的地址:
经过测试说明服务端接口返回正常:
Webservice客户端代码实现
public class Client {
public static void main(String args[]) {
Client.main1();
}
//调接口有两种方法
public static void main1(){
try {
System.out.println("Server is using...");
JaxWsDynamicClientFactory jaxWsDynamicClientFactory = JaxWsDynamicClientFactory.newInstance();
org.apache.cxf.endpoint.Client client = jaxWsDynamicClientFactory.createClient("http://localhost:8080/service/hello?wsdl");
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));这是访问接口的权限控制
Object[] contens = client.invoke("sayhai", "小明");//方法名,参数
/*
* 操作返回的数据
* */
System.out.println(contens[0]);
} catch (Exception e) {
System.out.println(e);
}
}
public static void main2(){
try {
String address="http://localhost:8080/service/hello?wsdl";
//代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean=new JaxWsProxyFactoryBean();
//设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
//设置接口类型
jaxWsProxyFactoryBean.setServiceClass(HelloWord.class);
//创建一个代理接口实现
HelloWord helloWord=(HelloWord)jaxWsProxyFactoryBean.create();
//数据
String name="小明";
//调用代理接口的方法调用并返回结果
String res=helloWord.sayhai(name);
System.out.println("****************"+res);
}catch (Exception e){
System.out.println(e);
}
}
}
- 客户端有两种方式去调用服务端的接口,一种是通过代理工厂的方式,一种的动态的创建客户端。
总结:还没有项目可以提供我练手,真正实现起来肯定还会有很多我现在没遇到的问题。按照目前的项目而言,就算有项目需要用到webservice,应该也只是实现客户端调用人家的接口。在查阅资料的时候看了一眼。基于局域网部署的,同一台服务器的两个系统如果要相互调用对方的接口,用webservice实现就不适用了,第一耗能严重,第二有更小更轻便的技术可以去实现。之后要学习的思路不仅限于学了一个组件,一个技术,还要了解和他相近的,是在他之前还是之后出现的技术,他们之间的联系和优缺点。