下面将介绍基于CXF的三种客户端的开发方法,主要用来自己开发的webservice 的测试及调用其他系统开发的服务端。
1.1.纯java 代码调用-最简单
Java 代码调用主要使用纯代码的方式来实现webservice 调用,主要实现类是:JaxWsProxyFactoryBean。
1.1.1. 样例
样例代码:
// 创建WebService客户端代理工厂
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
// 注册WebService接口
factory.setServiceClass(IAvnTboxChangeTCMP.class);
// 设置WebService地址
factory.setAddress("http://localhost:8080/XXX/services/xxxx");
IAvnTboxChangeTCMP client = (IAvnTboxChangeTCMP) factory.create();
//AVN成功测试
System.out.println("avnTboxChangeService 测试结果:"+client.changeAvnTbox("0", "VIN20121228TEST01", null, "测试维修店5", "王五", "2013-01-11 08:40:00", "AVN_SNTEST0006 DC23", "AVN_SNTEST0006 DC25", null, null, null, null));
在这种方式中,也主要设置接口类和wsdl 地址(上述例子中的红色标注部分)。
1.1.2. 缺点
如果是测试自己开发的webservice端,非常方便,只需要编写前面的代码。
如果是调用别人开发的webservice 端,需要自己通过wsdl2java 生成接口类或是对方提供接口类或是自己根据wsdl编写接口类。
1.2. Java+Spring配置文件-最易扩展
这种实现方式主要是将需要配置的东西从代码抽取到配置文件中,对于调用其他系统开发的webservice 非常有好处。
1.2.1. 样例
配置文件:
<bean id="avnTboxChangeTCMPClient" class="com.saicmotor.mce550.tsgp.tcmp.interf.avnTboxChange.IAvnTboxChangeTCMP" factory-bean="avnTboxChangeTCMPClientFactory" factory-method="create"/>
<bean id="avnTboxChangeTCMPClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.saicmotor.mce550.tsgp.tcmp.interf.avnTboxChange.IAvnTboxChangeTCMP"/>
<property name="address" value="http://localhost:8080/TCMP.Web/services/AvnTboxChangeTCMP"/>
</bean>
Java 代码:
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext(new String[] {"com/saicmotor/mce550/tsgp/tcmp/interf/client/avnTboxChange/client-beans.xml"});
IAvnTboxChangeTCMP client = (IAvnTboxChangeTCMP)context.getBean("avnTboxChangeTCMPClient");
String response = client.changeAvnTbox("0", "VIN20121228TEST03", null, "测试维修店2", "李四", "2013-01-08 08:40:00", "AVN_SNTEST0003 DC20", "AVN_SNTEST0003 DC28", null, null, null, null);
这种实现方式只需要加载对应的配置文件,然后通过spring 获取bean 对象的方法,获取到最终的调用客户端实例,然后调用具体的方法就可以了。
1.2.2. 缺点
如果是测试自己开发的webservice端,非常方便,只需要编写前面的代码。
如果是调用别人开发的webservice 端,需要自己通过wsdl2java 生成接口类或是对方提供接口类或是自己根据wsdl编写接口类。
1.3. Wsdl2Java生成-实现最快
下面将介绍cxf 自带的生成工具wsdl2java 的生成方式。
对应的工具目录在CXF_HOME\bin,需要切换到这个目录或是将这个路径配置到环境变量的PATH中。
1.3.1. Wsdl2java 命令
命令:
Wsdl2java -d {x} -p {x} wsdl
举例:
wsdl2java -d p:\client -p com.saicmotor.mce550.tsgp.tcmp.interf.client.generate <http://10.91.241.193:8080/TCMP.Web/services/AvnTboxChangeTCMP?wsdl>
参数说明: -d:指定生成的文件目录。
-p:指定生成代码的包名,很重要,否则会调用时报错。
wsdl:对应的wsdl 文件地址。
上面的代码会生成六个文件:
AvnTboxChangeTCMPImplService.java:对应webservice 的调用实现类。
ChangeAvnTbox.java:输入参数对象
ChangeAvnTboxResponse.java:返回参数对象
IAvnTboxChangeTCMP.java:对应webservice的接口类
ObjectFactory.java:输入输出对象的工厂类
package-info.java:生成的代码的package信息与wsdl 文件的命名空间对应。
生成下面六个文件之后,就可以编写测试类进行测试,举例如下:
public class client {
public static void main(String[] args){
AvnTboxChangeTCMPImplService client = new AvnTboxChangeTCMPImplService();
String respone = client.getAvnTboxChangeTCMPImplPort().changeAvnTbox("0", "VIN20121228TEST01", null, "测试维修店5", "王五", "2013-01-11 08:40:00", "AVN_SNTEST0006 DC23", "AVN_SNTEST0006 DC25", null, null, null, null);
System.out.println(respone);
}
}
1.3.2. Wsdl2java 生成客户端测试类
上面的客户端调用程序是我们自己编写的,当然也可以让wsdl2java 自己生成。
命令:
Wsdl2java -d {xx} -p {x} -client wsdl
举例:
wsdl2java -d p:\client -client -p com.saicmotor.mce550.tsgp.tcmp.interf.client.generate <http://10.91.241.193:8080/TCMP.Web/services/AvnTboxChangeTCMP?wsdl>
通过这个命令会多生成一个文件:
IAvnTboxChangeTCMP_AvnTboxChangeTCMPImplPort_Client.java: 自动生成的测试类。
在这个测试类中,会生成完整的测试代码,只需要进行参数赋值即可。
生成的代码如下:
public final class IAvnTboxChangeTCMP_AvnTboxChangeTCMPImplPort_Client {
private static final QName SERVICE_NAME = new QName("http://avnTboxChange.interf.tcmp.tsgp.mce550.saicmotor.com/", "AvnTboxChangeTCMPImplService");
private IAvnTboxChangeTCMP_AvnTboxChangeTCMPImplPort_Client() {
}
public static void main(String args[]) throws Exception {
URL wsdlURL = AvnTboxChangeTCMPImplService.WSDL_LOCATION;
if (args.length > 0) {
File wsdlFile = new File(args[0]);
try {
if (wsdlFile.exists()) {
wsdlURL = wsdlFile.toURI().toURL();
} else {
wsdlURL = new URL(args[0]);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
AvnTboxChangeTCMPImplService ss = new AvnTboxChangeTCMPImplService(wsdlURL, SERVICE_NAME);
IAvnTboxChangeTCMP port = ss.getAvnTboxChangeTCMPImplPort();
{
System.out.println("Invoking changeAvnTbox...");
java.lang.String _changeAvnTbox_arg0 = "0";
java.lang.String _changeAvnTbox_arg1 = "VIN20121228TEST01";
java.lang.String _changeAvnTbox_arg2 = "";
java.lang.String _changeAvnTbox_arg3 = "测试维修店5";
java.lang.String _changeAvnTbox_arg4 = "王五";
java.lang.String _changeAvnTbox_arg5 = "2013-01-11 08:40:00";
java.lang.String _changeAvnTbox_arg6 = "AVN_SNTEST0006 DC23";
java.lang.String _changeAvnTbox_arg7 = "AVN_SNTEST0006 DC25";
java.lang.String _changeAvnTbox_arg8 = "";
java.lang.String _changeAvnTbox_arg9 = "";
java.lang.String _changeAvnTbox_arg10 = "";
java.lang.String _changeAvnTbox_arg11 = "";
java.lang.String _changeAvnTbox__return = port.changeAvnTbox(_changeAvnTbox_arg0, _changeAvnTbox_arg1, _changeAvnTbox_arg2, _changeAvnTbox_arg3, _changeAvnTbox_arg4, _changeAvnTbox_arg5, _changeAvnTbox_arg6, _changeAvnTbox_arg7, _changeAvnTbox_arg8, _changeAvnTbox_arg9, _changeAvnTbox_arg10, _changeAvnTbox_arg11);
System.out.println("changeAvnTbox.result=" + _changeAvnTbox__return);
}
System.exit(0);
}
}
1.3.3. 缺点
此种生成方式实现最快,几乎不需要编写什么代码,但是生成的类太多,扩展性不是很好,不利于上手。