CXF:基于JAX-WS的webservice

阅读更多

本文主要涉及的webservice采用SOAP协议、采用JAX-WS作为前端、JAXB数据绑定。需要加入以下依赖:


	org.apache.cxf
	cxf-rt-frontend-jaxws
	2.7.0



	org.apache.cxf
	cxf-rt-bindings-soap
	2.7.0



	org.apache.cxf
	cxf-rt-databinding-jaxb
	2.7.0



	org.apache.cxf
	cxf-rt-transports-http
	2.7.0

1、server端

与之前基于JAX-WS的webservice一致,作为前端并不需要有任何修改。在这个例子中包含了传递String、自定义对象、Map等

@WebService(serviceName = "cxfServer")
public class CXFServiceImpl implements CXFService {

    @Override
    @WebMethod
    public String sayHello(String name) {
        return "Hello, " + name + ", from CXF";
    }

    @Override
    @WebMethod
    @WebResult
    @XmlJavaTypeAdapter(value = MapAdapter.class)
    public Map queryPerson() {
        Map map = new HashMap();
        map.put("p1", new Person("robin", "robin_123"));
        map.put("p2", new Person("ace", "ace_456"));
        return map;
    }

    @Override
    @WebMethod
    public void savePerson(@WebParam List list) {
        if (list != null && !list.isEmpty()) {
            for (Person person : list) {
                System.out.println(ToStringBuilder.reflectionToString(person, ToStringStyle.SHORT_PREFIX_STYLE));
            }
        }
    }

}

注意对传递Map,在JAX-WS是不能直接传递,需要作为一个包装类传递。而在CXF中则可以直接传递,这里还是采用JAXB作为解析对象故这里的MapAdapter与之前的一致.见这里

 

2、发布为一个webservice

1、jaxwsserver

JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(CXFServiceImpl.class);
factory.setAddress("http://localhost:8080/service/helloCxfService");
//optional: set in interceptors
factory.getInInterceptors().add(new LoggingInInterceptor());
//optional: set out interceptors
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.create();

由于采用jetty作为默认的Server的实现,需要加入


	org.apache.cxf
	cxf-rt-transports-http-jetty
	2.7.0

 运行后即可通过http://localhost:8080/service/helloCxfService?wsdl查看发布结果。或者可以通过这样测试

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(CXFService.class);
factory.setAddress("http://localhost:8080/service/helloCxfService");
CXFService server = (CXFService) factory.create();
 

2、spring集成的几种方式

需要在spring的配置文件加入相应的schema及location:

xmlns:jaxws="http://cxf.apache.org/jaxws"
http://cxf.apache.org/jaxws 
http://cxf.apache.org/schemas/jaxws.xsd



打开位于cxf-rt-frontend-jaxws-2.7.0.jar/schemas/jaxws.xsd文件,我们查看定义了三种方式:

 

jaxws:endpoint
jaxws:server
jaxws:client

前两者用来申明发布server,后者作为客户端的配置。下面来看看与spring继承的几种方式:

1、采用jaxws:server配置



	
		
	
	
		
	
	
		
	
这里jaxws:endpoint的配置大同小异,具体参数配置见jaxws.xsd

CXF:基于JAX-WS的webservice_第1张图片

 

2、由于采用JAX-WS作为前端,作为对JaxWsServerFactoryBean实例的注入:



	
	
	
		
			
		
	
	
		
			
		
	

factory-bean="cxfServiceFactory" factory-method="create" />

  针对上面两种配置,可以通过在http://localhost:8080/service/helloCxf?wsdl访问发布成功与否。当然上面的address采用了绝对路径,实际上和web项目的整合只需要指定到相对路径即可。

3、与web项目(tomcat)
还是采用上面第二种配置,这里只需要修改address的路径如:
在web.xml中需要添加一个servlet对请求的拦截处理,如:

	CXFServlet
	org.apache.cxf.transport.servlet.CXFServlet
	1


	CXFServlet
	/service/*
 运行后即可通过容器发布的路径访问,如:http://localhost:8080/webservice/service/helloCxf?wsdl

 

3、客户端访问

以上都是讲述的服务端的实现,如何发布一个服务。在上面的各种服务都是基于SOAP协议,用户可以获得生产的wsdl文件,来生产相应的客户端代码来完成远程的调用。在前面介绍JAX-WS的时候讲解了两种工具来生产客户端代码:wsimport/wsgen。而CXF也同样提供了类似的一些列工具,这里正对这种场景我们需要用到的是wsdl2java,位于CXF_HOME/bin目录
可以通过wsdl2java -help来看具体的参数,这里生产一个客户端代码如下:
wsdl2java -p org.sample.ws.client.cxf.chap1 -keep -verbose http://localhost:8080/webservice/service/helloCxf?wsdl
这样在指定的包下就生产了客户端代码。下面通过spring配置类测试客户端的调用,与上面发布服务一样,通过两种方式:
1、作为jaxws:client调用:

	
		
	
	
		
	
 这里需要注意哪些配置是作为element哪些是attribute
CXF:基于JAX-WS的webservice_第2张图片
2、作为对JaxWsProxyFactoryBean注入的实现:


	
	
	
		
			
		
	
	
		
			
		
	


客户端测试代码:
ClassPathXmlApplicationContext xmlApplication = new ClassPathXmlApplicationContext("cxf-spring.xml");
CXFService service = (CXFService) xmlApplication.getBean("helloCxfService");
System.out.println(service.sayHello("robin"));

4、异步

由于采用JAX-WS作为前端,针对之前在用JAX-WS发布异步服务,我们这里也可以采用相同的方式:
编写binding.xml文件,指定异步方式:

	
		true
	
在生成客户端的时候需要指定该binding.xml文件
wsdl2java -p org.sample.ws.client.cxf.chap2 -b .\binding.xml -keep -verbose http://localhost:8080/webservice/service/helloCxf?wsdl
测试:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(CXFService.class);
factory.setAddress("http://localhost:8080/webservice/service/helloCxf");
CXFService server = (CXFService) factory.create();

System.out.println("同步--> server.sayHello(\"robin\"):  " + server.sayHello("robin"));

Response response = server.sayHelloAsync("robin");
while (!response.isDone()) {
    System.out.println("异步调用......");
}
System.out.println("异步: " + response.get().getReturn());
 

你可能感兴趣的:(cxf,jaxws,异步,前端,webservice)