有时并不想用注释类或使用JAX-WS API.CXF包含一个简单的Frontend,允许你把任何类发布成web service且不需要额外的工作。不需要在业务接口中设置具体的协议、@Web Service、@Web Method,仅仅需要创建与具体webservice技术无关的业务接口就可以了, 利用代理类进行发布服务和获取服务
一.简单实例
1. 编写业务接口和类:
public interface HelloWorld {
String sayHello(String text);
}
public class HelloWorldImpl implements HelloWorld {
public String sayHello(String text) {
return "Hello " + text;
}
}
2. 发布web service
import org.apache.cxf.frontend.ServerFactoryBean;
public class Server {
protected Server() throws Exception
{
HelloWorldImpl 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 Server();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
3. 测试 输入:http://localhost:9000/Hello?wsdl
4. 客户端:
需要创建与具体webservice技术无关的业务接口HelloWorld
public interface HelloWorld {
String sayHello(String text);
}
5. 调用web service
import org.apache.cxf.frontend.ClientProxyFactoryBean;
/**
* 客户端
* 仅仅需要一个与具体技术无关的java接口HelloWorld
*/
public class Client {
public static void main(String args[]) throws Exception
{
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
//设置已发布服务接口
factory.setServiceClass(HelloWorld.class);
//为客户端代理bean 设置已经发布的服务地址
factory.setAddress("http://localhost:9000/Hello");
//获取已发布服务接口实例
HelloWorld client = (HelloWorld)factory.create();
System.out.println(client.sayHello("Tom"));
System.exit(0);
}
}
二.与spring集成
1. 发布的web service,如果与spring集成,只需要加一个配置文件就可以了:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:simple="http://cxf.apache.org/simple"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd">
<simple:server id="helloservice" serviceClass="frontend.HelloWorld" address="/hello">
<simple:serviceBean>
<bean class="frontend.HelloWorldImpl" />
</simple:serviceBean>
</simple:server>
</beans>
发布到tomcat下即可,访问:http://localhost:8080/<web_project_name>/ws/hello?wsdl
ws为web.xml中配置的CXFServlet映射路径。
2. 配置客户端spring-client.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
<bean id="frontendClient" class="frontend.HelloWorld"
factory-bean="frontendClientFactory" factory-method="create" />
<bean id="frontendClientFactory" class="org.apache.cxf.frontend.ClientProxyFactoryBean">
<property name="serviceClass" value="frontend.HelloWorld" />
<property name="address"
value="http://localhost:9000/Hello" />
</bean>
</beans>
3. 测试
public class SpringTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-client.xml");
HelloWorld client = (HelloWorld) ctx.getBean("frontendClient");
String result = client.sayHello("你好!");
System.out.println(result);
}
}
三.采用Aegis数据绑定
如果采用simple frontend方式发布复杂的web service 有自定义数据,默认的情况是采用JAXB绑定,如果你不想用注释,那就用Aegis数据绑定。
Aegis是一个快速,基于STAX(Streaming API for XML)的数据绑定,它能使采用代码优先方式发布web service的情况更简单。Aegis 支持接口,集合类(包括Map)和各种数据类型。
1、 编写复杂的业务接口和实现类
public interface HelloWorld {
String sayHello(String text);
String sayUserHello(User user);
List<User> findUsers();
Map<Integer, User> getMapUsers();
}
其实的和普通的java区别,不用写xmlAdapter,也不用注释。
2、 发布web service
只要在发布web service时加上:svrFactory.getServiceFactory().setDataBinding(new AegisDatabinding());
具体如下:
protected Server() throws Exception
{
HelloWorldImpl helloworldImpl = new HelloWorldImpl();
ServerFactoryBean svrFactory = new ServerFactoryBean();
//设置服务接口类
svrFactory.setServiceClass(HelloWorld.class);
svrFactory.setAddress("http://localhost:9000/Hello");
//设置服务实现接口类
svrFactory.setServiceBean(helloworldImpl);
//采用Aegis方式进行数据绑定
svrFactory.getServiceFactory().setDataBinding(new AegisDatabinding());
//创建服务
svrFactory.create();
}
3、 客户端
创建与具体webservice技术无关的业务接口,因为传递的是User接口,所以要在客户端加上
User 接口和UserImple类
public interface User {
String getPassword();
String getUsername();
void setUsername(String username);
void setPassword(String password);
void setUserId(Integer userId);
Integer getUserId();
}
public class UserImpl implements User {
private Integer userId;
private String username;
private String password;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public UserImpl(String username, String password) {
super();
this.username = username;
this.password = password;
}
public UserImpl() {
}
public UserImpl(String username) {
this.username = username;
}
public UserImpl(Integer userId, String username, String password) {
this.userId = userId;
this.username = username;
this.password = password;
}
}
4、 测试,调用web service.
其中最关键要加上:
factory.getServiceFactory().setDataBinding(new AegisDatabinding());
public class Client {
public static void main(String args[]) throws Exception
{
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
//设置已发布服务接口
factory.setServiceClass(HelloWorld.class);
//为客户端代理bean 设置已经发布的服务地址
factory.setAddress("http://localhost:9000/Hello");
//采用Aegis数据绑定
factory.getServiceFactory().setDataBinding(new AegisDatabinding());
//获取已发布服务接口实例
HelloWorld client = (HelloWorld)factory.create();
System.out.println(client.sayHello("Tom"));
System.out.println(client.sayUserHello(new UserImpl("aaa1111111111","bbb")));
List<User> list = client.findUsers();
Iterator<User> i = list.iterator();
while (i.hasNext()) {
User u = i.next();
System.out.println(u.getUsername());
}
System.out.println("--------------------");
Map<Integer ,User> map = client.getMapUsers();
for (Integer e : map.keySet()) {
// System.out.println(e);
System.out.println(map.get(e).getUsername());
}
System.exit(0);
}
}
5、 与spring集成:
服务器的spring-cxf.xml的配置文件中加上:<simple:dataBinding>部分。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:simple="http://cxf.apache.org/simple"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd">
<simple:server id="helloservice" serviceClass="frontend.HelloWorld" address="/hello">
<simple:serviceBean>
<bean class="frontend.HelloWorldImpl" />
</simple:serviceBean>
<simple:dataBinding>
<bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
</simple:dataBinding>
</simple:server>
</beans>
客户端的配置文件修改spring-client.xml如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
<bean id="frontendClient" class="frontend.HelloWorld"
factory-bean="frontendClientFactory" factory-method="create" />
<bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" scope="prototype"/>
<bean id="frontendClientFactory" class="org.apache.cxf.frontend.ClientProxyFactoryBean">
<property name ="dataBinding" ref="aegisBean"/>
<property name="serviceClass" value="frontend.HelloWorld" />
<property name="address"
value="http://localhost:9000/Hello" />
</bean>
</beans>
四.后记
感觉采用这种方式(Frontend+Aegiis)发布和获取web service要比采用JAX-WS Annotated Services from Java+JAXB组合要简单一些.