/**
* 使用ServerFactoryBean发布服务
* 使用CXF发布一个服务,与JDK6发布一个服务完全不同
* 即使是不使用@WebService注解,一样可以发布成功
* 即使此类没有对外公布的方法一样可以发布成功
*/
publicclass CxfOneServer {
public String sayHi(){
return "Hello:"+new Date();
}
public static void main(String[] args) {
ServerFactoryBean bean =//声明实例
new ServerFactoryBean();
//绑定到发布地址的端口
bean.setAddress("http://127.0.0.1:9999/one");
//设置服务接口,如果没有接口,则为本类
bean.setServiceClass(CxfOneServer.class);
//设置接口实现类,即服务类
bean.setServiceBean(new CxfOneServer());
bean.create();//发布服务
System.err.println("启动成功");
}
}
客户端
publicclass Client {
public static void main(String[] args) {
ClientProxyFactoryBean bean =//创建客户端类
new ClientProxyFactoryBean();
//设置访问地址
bean.setAddress("http://localhost:9999/one");
//设置服务接口,直接使用本项目中的接口
bean.setServiceClass(CxfOne.class);
//通过create方法返回接口实例
CxfOne s = (CxfOne) bean.create();
String str = s.sayHi();//调用
System.err.println(str);
}
}
出错,但也不会对外暴露任何方法。
使用此类生成的wsdl文件更加规范。
@WebService
publicclass OneService {
public String sayHi(){
return "Good";
}
public static void main(String[] args) throwsException {
JaxWsServerFactoryBeanbean //使用jaxWs对其进行发布
= new JaxWsServerFactoryBean();
bean.setServiceBean(new OneService());
bean.setServiceClass(OneService.class);
bean.setAddress("http://localhost:4444/one");
bean.create();
System.err.println("服务启动成功。。");
//Thread.sleep(1000*60*60);
//System.exit(0);
}
}
在服务启动成功后,访问的方式为:http://localhost:4444/one?wsdl
创建成功以后,使用Wsimport或者wsdl2java生成的客户端代码,同样可以调用成功。
使用JaxWsProxyFactoryBean客户端调用
publicclass A{
publicstaticvoidmain(String[] args) {
//Cxf2Servert =
//newCxf2ServerService().getCxf2ServerPort();
//Strings = t.sayHello();
//System.err.println(s);
JaxWsProxyFactoryBean bean =
newJaxWsProxyFactoryBean();
bean.setAddress("http://localhost:9999/two");
//此外注册的必须是一个接口,否则将抛出异常信息
bean.setServiceClass(Cxf2Server.class);
Cxf2Servers = (Cxf2Server) bean.create();
System.err.println(s.sayHello());
}
}
如果不是使用spring的配置文件发布,可以没有接口文件,但在任何情况下建议拥有接口文件。如果使用spring的配置文件发布,则必须要拥有接口类。
wsdl2java生成客户代码:
1、注意:由于使用的是apache-cxf-2.4.0版本,它是支持jdk1.7的。所以,对于生成的Service要进行稍微的修改。
在jdk1.6中的javax.xml.ws.Service的构造方法接收二个参数为:(String url,QNameqname);
在jdk1.7中的javax.xml.ws.Service的构造方法中接收三个参数为:(String url,QNameqname,features);
2、将生成的代码,拷贝到项目目录,然后使用以前相同方法调用。
注意:如果你对@WebMethod设置了header=true参数,将会在调用时多传递一个参数。它参数可以直接传null值。
对于这种情况,可以将header=true修改成header=false然后再重要获取客户端源代码。
3、使用cxf生成的客户端代码与wsimport差不多,甚至是一样,那为什么还要使用cxf呢?
它较好的发布方式、较容易的与其他服务器集成、及与Spring的完美结合都不得不让我们使用cxf。
/**
* 使用java6来调用cxf生成的客户端类的服务
* 不管是用wsimport还是用wsdl2java生成的类基本上是完全一样的
*/
publicclass CxfServerJava6Client {
public static void main(String[] args) {
//调用使用wsimport生成的代码
IHelloWorldPortType hello =new IHelloWorld().getIHelloWorldPort();
String str = hello.sayHello("小王");
System.err.println(str);
//调用使用wsdl2java生成的代码(一样)
com.itcast.cxfserver2.javaclient.IHelloWorldPortTypeclient =
newcom.itcast.cxfserver2.javaclient.IHelloWorld().getIHelloWorldPort();
String str2 = client.sayHello("CXF");
System.err.println(str2);
}
}
要想研究更多程序请见:cxf2.4_ws服务项目和cxf2.4_java6client客户端项目。
给服务器添加拦截器,类似于使用TCP/IPMonitor来捕获SOAP消息的过程。
server.getInInterceptors().add(newLoggingInInterceptor());
server.getOutInterceptors().add(newLoggingOutInterceptor());