什么是WebService?
webservice直译网络服务,是RPC的一样实方式。
RPC(Remote Procedure Call Protocol)---远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
客户端要能调用服务端必须遵循TCP协议,而webservice使用的是更高一级的HTTP协议,
客户端访问服务器的目的是为了获取数据,那数据必须是与平台、语言无关的。webservice采用的是XML。
使用场景
- 由权威机构提供的第三方小功能(天气、百度地图…)
权威机构能够获取一些普通人没法获取的数据,然后他们把封装成ws服务端,普通人使用就作为webservice客户端调用服务端 - 多种客户端数据获取整合
一些大型应用公司(比如腾讯)为了提高影响力,它会针对不同平台(pc浏览器、手机浏览器、手机app) 提供开发不同的客户端,而客户端需要调用获取数据,使用prc、webservice就是一种实现方式。
如下图所示:如果现在手机APP(它是没有页面,想要数据),那么就要为它提供接口,供调用方使用接口。那么接口实现制者和接口调用者之间需要遵循一个规范,说白了接口约束就是为了统一规范。
下面介绍为什么要用webservice?
解决异构系统中的信息孤岛问题
针对上面情况,我们可在企业系统里搭建一根总线—ESB(企业服务总线),用来连接企业里各个系统的服务,每个系统和总线连起来,用XML传输数据
企业中所有的服务都要注册到总线,其他系统要想调用服务,必须先从总线寻找服务,才来完成调用(也就是webservice+esb)这样解决的问题:每个系统不会直接暴露webservice,如果直接暴露,大家相互依赖。随着系统业务量的增长,服务管理比较麻烦,所以通过webservice+esb解决问题。
总结:webservice是一种基于http协议和XML技术,并使用WSDL描述和使用SOAP协议传输的异构系统解决方案
***接下来简单介绍一下:基于jdk方式构建webservice ***
基于jdk构建webservice server端
- 创建项目
- 创建本次服务接口和实现类
- 把本地服务标记为远程服务
- 发布服务
- 测试 -根据注解来做一些事情
/**
* 只要在某个接口上添加了@WebService 那么在所有的方法上面都会加上@WebMethod
* @author 以梦为马 不负韶华
* @WebMethod operationName="sayHello" 更改暴露的方法名 exclude=true排除方法
*创建接口
*/
@WebService
@SOAPBinding(style=Style.RPC) //默认document ,rpc少了一些类型
public interface IHelloService {
//@WebParam(name="name") x修改参数名称
//@WebResult(name="ret") 修改返回值名称
@WebResult(name="ret") String sayHi(@WebParam(name="name")String name);
}
package com.zj.ws.jdk.server.tag;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
//只要加上@WebService 标识是一个远程服务类
//endpointInterface 指定接口
//serviceName 服务名 portName 端口名 targetName 限定名、实现类改了接口也要跟着改
//创建接口实现类
@WebService(endpointInterface="com.zj.ws.jdk.server.tag.IHelloService",
serviceName="helloService")
public class IHelloServiceImpl implements IHelloService{
@Override
public String sayHi(String name) {
// TODO Auto-generated method stub
return name+" say you is db!";
}
}
package com.zj.ws.jdk.server.tag;
import javax.xml.ws.Endpoint;
import com.zj.ws.jdk.server.tag.IHelloServiceImpl;
//发布服务
public class Publish {
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:8888/hi",new IHelloServiceImpl());
System.out.println("服务发布成功");
}
}
服务发布成功后 通过浏览器访问地址 注意:jdk1.8 http://192.168.0.103:8888/hello 不能直接访问地址 要加上?wsdl 需要加一个描述
接下对刚刚出现的wsdl做个描述,以及访问结束后XML格式文件做个介绍:
wsdl简介
1.是什么
web service description language 网络服务描述语言,简单理解就是用来描述服务的
2.结构讲解
definitions 根
name:服务名称,类型+Service
targetNamespace:http://倒置包名
service:服务接口
<soap:address location=“http://127.0.0.1:8888/hello”/> 服务在哪个地址上能够被访问
binding:
<soap:binding transport=“http://schemas.xmlsoap.org/soap/http” style=“document”/>
transport:什么样的传输协议来调用
style=“document”:表示我们wadl文件遵循什么格式,默认document 还有RPC
portType:接口类型
描述了有哪些接口方法
message:消息
描述接口方法的参数和返回值消息
types:描述消息的类型和名称–在document才有,而rpc没有
基于jdk构建webservice client端
- 创建项目
- 通过wsdl地址生成本地接口
使用jdk的一个工具wsimport-jdk\bin,想在任意路径调用,需要配置path
wsimport -s . http://127.0.0.1:8888/hello?wsdl (通过命令生成本地代码)注意:不要把服务端关了 - 通过生成一些类获取本地接口代理对象
- 通过该本地代理对象的方法就能远程调用服务
/**
* 获取本地接口代理对象并且完成调用
* @author 以梦为马 不负韶华
*
*/
public class Invoke {
public static void main(String[] args) {
//获取本地接口代理对象
HelloServiceImpl helloService= new HelloServiceImplService().getHelloServiceImplPort();
System.out.println(helloService.getClass());
//通过代理对象调用远程服务方法
System.out.println(helloService.sayHello("as"));;
}
}
**
再来说下基于第三方框架CXF实现webservice客户端和服务端
支持ESB+webservice
下载Apache 第三方框架:apache-cxf-3.2.12-src
需要配置环境变量:
因为它内置jetty所以还需要jettyjar包
因为服务端发布服务时需要jetty 而客户端只是调用服务不需要jetty
为什么要把jetty放个文件夹 因为后续如果用Tomcat 就不要jetty了
JaxWsServerFactoryBean 是支持注解的
Client-cxf
package com.zj.server.cxf;
import javax.jws.WebService;
@WebService
public interface IHelloService {
String sayX(String name);
}
package com.zj.server.cxf;
import javax.jws.WebService;
@WebService(endpointInterface="com.zj.server.cxf.IHelloService")
public class IHelloServiceImpl implements IHelloService{
@Override
public String sayX(String name) {
// TODO Auto-generated method stub
return name+"测试============";
}
}
package com.zj.server.cxf;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class Publish {
public static void main(String[] args) {
/**
* 1.创建JaxWsServerFactoryBean的对象 用于发布服务
* 2.设置服务发布地址
* 3.设置服务发布的接口
* 4.设置服务的发布对象
* 5.使用Create方法发布服务
*/
JaxWsServerFactoryBean factoryBean=new JaxWsServerFactoryBean();
factoryBean.setAddress("http://127.0.0.1:9999/hi");
factoryBean.setServiceClass(IHelloService.class);
factoryBean.setServiceBean(new IHelloServiceImpl());
factoryBean.create();
System.out.println("发布服务成功");
}
}
配置好环境变量生成client代码 然后只需要留IHelloService接口代码
package cn.zj.ws.client.cxf;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class Invoke {
public static void main(String[] args) {
//1.创建的对象,用于接收服务
JaxWsProxyFactoryBean bean=new JaxWsProxyFactoryBean();
//2.设置服务的发布接口,表示去哪里服务
bean.setAddress("http://127.0.0.1:9999/hi");
//3.设置服务的发布接口,使用本地的代理接口
bean.setServiceClass(IHelloService.class);
//通过create方法返回接口代理对象实例
IHelloService helloService=(IHelloService)bean.create();
//验证是否是代理对象
System.out.println(helloService.getClass());
//调用远程方法
System.out.println(helloService.sayX("张三"));
}
}
最终完成基于第三方框架实现webservice,当然梳理比较粗,并且目前webservice是个比较老一点的技术。