首先,再次进行说明,通俗的说,webService的功能就是可以实现跨平台、跨语言的远程调用。
最基础的平台是xml+http。
WebService平台的元素:soap协议(简单对象访问协议),WSDL(Web Service Describe language,网络服务描述语言)。
其实这里我不想再写代码了,原理才是最重要的。
下面是我画的原理图:
我的上一篇日志中说过用JDK自带的Endpoint发布WebService和调用WebService的方法了。最近有研究了使用cxf来发布和调用WebService的方式。
看这篇日志的人应该也都是内行,cxf是Apache开源基金会下的一个开源的项目,也是Celtix + XFire的混合体,我现在大概知道这么多。
首先,需要的同学可以去Apache的官网上去下载。
第二步:如果你要使用wsdl2java命令来根据webService发布在网络上的API来生成本地代码(可以只生成java文件,不生成.class文件,wsdl2java -s . url);
第三步:发布或者调用服务。
发布服务时,可能需要用到的类:
1. ServerFactoryBean,该类可用于发布soap1.1版本协议的服务;
2. JaxWsServerFactoryBean,这是ServerFactoryBean的增强子类,可用于发布soap1.2版本的协议;
注意:如果使用的协议为soap1.2的版本(即在接口上使用@BindingType(SOAPBinding.SOAP12HTTP_BINDING)),那么在使用wsimport命令生成本地代码时,需要加上-extension命令来生成相关接口文件。
发布的流程为:
第一步:创建发布类对象;
第二步:设置webService服务的地址;
第三步:设置webService的接口类型;
第四步:设置webService的实现类;
第五步(可以略过):这里可以设置下是否对消息进行拦截;
第六步:发布服务;
同样,对应的客户端访问类:
1. ServerFactoryBean对应的是ClientProxyFactoryBean
2. JaxWsServerFactoryBean对应的客户端访问类是JaxWsProxyFactoryBean.
访问服务的大概流程:
第一步:创建访问webService服务的实例;
第二步:设置需要访问的webService的网络地址;
第三步:设置接口类型;
第四步:创建接口实例;
第五步:调用相关接口的方法(远程调用);
(我想说代码不是最重要的,重要的是理解里面的原理,运行的机制,底层都是jdk中的Socket)。
下面的代码是使用cxf发布和调用webService的例子:
这是一个没有实现接口的WebService,如果是接口,那么将注解打在接口上。
import javax.jws.WebService; @WebService public class CxfWebService { public void sayHello(){ System.out.println("hello!"); } }
使用ServerFactoryBean发布服务,
import org.apache.cxf.frontend.ServerFactoryBean;
public class CxfServer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建发布服务的类...
ServerFactoryBean bean=new ServerFactoryBean();
bean.setAddress("http://192.168.9.100:8080/server");//服务对外的访问地址
bean.setServiceClass(CxfWebService.class);//设置服务类的接口类型,如果没有接口则为当前类..
bean.setServiceBean(new CxfWebService());//设置服务类的实现
bean.create();//发布服务
}
}
客户端:
1. 使用wsimport命令生成本地java代码,将生成的接口拷贝到项目中来。
2. 使用ClientProxyFactoryBean类调用WebService服务;
具体代码如下:
import org.apache.cxf.frontend.ClientProxyFactoryBean;
/**
* 使用CXF提供的类 ClientProxyFactoryBean调用webService服务
* @author 肖云
*/
public class CxfClientInvoke {
public static void main(String[] args) {
// 创建调用webService服务的类
ClientProxyFactoryBean bean = new ClientProxyFactoryBean();
// 设置调用地址
bean.setAddress("http://192.168.0.102:8090/cxfService");
// 设置接口类型
bean.setServiceClass(CxfWebServicePortType.class);
// 创建接口类型的实例
CxfWebServicePortType cxfWebServicePortType = (CxfWebServicePortType) bean.create();
// 调用相关方法
cxfWebServicePortType.sayHello();
}
}
其中:
CxfWebServicePortType 类是使用wsimport生成的相关接口