最近使用了一下cxf,简单的查看了部分源代码,给我的感觉它就是一个可以大大简化我们客户端编写远程方法调用的一个工具框架,只需要简单的几行代码就可以解决这种复杂的问题,下面就举个例子:
package com.yonge.cxf;
import java.util.Date;
import org.apache.cxf.frontend.ClientProxyFactoryBean;
import org.apache.cxf.transport.jms.spec.JMSSpecConstants;
import com.erayt.solar2.adapter.config.Weather;
import com.erayt.solar2.adapter.fixed.HelloWorld;
public class CXFClientTest {
public static void main(String[] args) {
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress("http://localhost:9000/Hello");
HelloWorld hello = factory.create(HelloWorld.class);
Weather weather1 = hello.getWeather(new Date());
System.out.println("forecast:" + weather1.getForecast());
}
}
上面一段是客户端调用远程服务器中HelloWorld接口的getWeather方法 的一个具体实现。服务端的代码如下:
package com.erayt.solar2.adapter.driver;
import org.apache.cxf.frontend.ServerFactoryBean;
import com.erayt.solar2.adapter.config.HelloWorldImpl;
import com.erayt.solar2.adapter.fixed.HelloWorld;
public class CXFServer {
protected CXFServer() throws Exception {
HelloWorld helloworldImpl = new HelloWorldImpl();
ServerFactoryBean svrFactory = new ServerFactoryBean();
svrFactory.setServiceClass(HelloWorld.class);
svrFactory.setAddress("http://localhost:9000/Hello");
svrFactory.setServiceBean(helloworldImpl);
svrFactory.create();
}
public static void main(String args[]) throws Exception {
new CXFServer();
System.out.println("Server ready...");
Thread.sleep(50 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
服务端将接口以服务的形式发布后,必须提供客户端访问服务的地址(http://localhost:9000/Hello),客户端可以根据提供的地址访问服务端相关服务的wsdl文件,客户端可以根据wsdl文件生成对应的客户端代码,也就是HelloWorld接口文件,然后客户端可以像调用本地接口方法一样,去调用远程方法,客户端与服务端之间的交互是通过代理完成的,所以开发在编程时不需要关系他们是如何交互的,在代理中,上面的客户端请求hello.getWeather方法时会向服务端发送如下的消息:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns1:getWeather xmlns:ns1="http://fixed.adapter.solar2.erayt.com/"> <arg0>2013-06-22T18:56:43.808+08:00</arg0> </ns1:getWeather> </soap:Body> </soap:Envelope>
服务器端接收报文后,会解析报文,按照报文的信息执行相应的本地方法,然后将返回值又构造一个报文响应给客户端,如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns1:getWeatherResponse xmlns:ns1="http://fixed.adapter.solar2.erayt.com/"> <return> <forecast>Cloudy with showers </forecast> <howMuchRain>4.5</howMuchRain> <rain>true</rain> <temperature>39.3</temperature> </return> </ns1:getWeatherResponse> </soap:Body> </soap:Envelope>
代理接收消息后,会将他解析、包装成对象返回给客户端,最后开发就看到了服务器返回的数据了。在这里只介绍一下我理解的工作原理,详情可以去看官网的介绍http://cxf.apache.org/。