在选择WebService框架的过程中,偶最终选择了Apache CXF,純粹伿諟銦爲听说它与Spring的无缝整合
想当初用Axis的时候,因为没有太好的办法让Spring能够集成Axis,只好平白无故地多出一个WebService代理类,让偶的感觉很是不爽
偶要在此记载一下CXF的一些入门知识
首珗,倌網哋址諟http://cxf.apache.org/,里面可以找到User's Guide和download地址,偶的版本是目前最新的
apache-cxf-2.2.5
先来做一个最简单的入门级别例子吧,也就是经典的HelloWord
Server端代码
WebService接口HelloService.java
package cfx.server;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface HelloService {
@WebMethod
String sayHi(@WebParam String name);
}
实现类HelloServiceImpl.java
public class HelloServiceImpl implements HelloService {
public String sayHi(String name) {
System.out.println("HelloServiceImpl.sayHi called");
return "Hello"+name;
}
WebService配置文件:cxf-servlet.xml(可放置于WEB-INF目录下)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:server id="jaxwsService" serviceClass="cfx.server.HelloService" address="/hello">
<jaxws:serviceBean>
<bean class="cfx.server.HelloServiceImpl" />
</jaxws:serviceBean>
</jaxws:server>
</beans>
web.xml代码,用于添加CXFServlet这个处理webservice请求的控制器类
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
Client端测试代码
public class CXF {
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setServiceClass(HelloService.class);
factory.setAddress("http://localhost:8080/cxf/services/hello");
HelloService client = (HelloService) factory.create();
String reply = client.sayHi("特蕾莎");
System.out.println("Server said: " + reply);
}
*****************************************************************************
怎么样,是不是很简单啊!现在再来一个和Spring整合的例子
注意,Server端和Client端都要通过Spring-bean的方式整合
Server端现在有四个文件,假设是
HelloService.java
HelloServiceImpl.java
HelloDao.java
HelloDaoImpl.java
在HelloServiceImpl中存在一个HelloDao的属性,代码省略如下
public class HelloServiceImpl implements HelloService {
private HelloDao dao;
public String sayHi(String name) {
System.out.println("HelloServiceImpl.sayHi called");
return dao.getString(name);
}
}
HelloDaoImpl用于处理持久化,代码省略咯
需要修改的是配置文件,此时可以这样改
首先在web.xml里加入Spring监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
橪銗WEB-INF/cxf-servlet這個忟件可以省略咯
把一个标准的spring-bean文件放在src下(即classes目录下),要让人一看就知道spring大哥进来咯
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="helloDao" class="cfx.server.HelloDaoImpl" />
<jaxws:server id="jaxwsService" serviceClass="cfx.server.HelloService" address="/hello">
<jaxws:serviceBean>
<bean id="helloService" class="cfx.server.HelloServiceImpl">
<property name="dao" ref="helloDao" />
</bean>
</jaxws:serviceBean>
</jaxws:server>
</beans>
這樣啟動服務器的时候,spring就自动进行bean的注入以及WebService服务的发布了
接下来是客户端代码
銦爲諟普通Java,所以就简单配一下愙戸端的spring文件了
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
<bean id="HelloService" class="cfx.server.HelloService" factory-bean="clientFactory" factory-method="create" />
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="cfx.server.HelloService" />
<property name="address" value="http://localhost:8080/cxf/services/hello" />
</bean>
</beans>
CXFClientTest.java
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "cfx/client/client-beans.xml" });
HelloService client = (HelloService) context.getBean("HelloService");
testString(client);
}
static void testString(HelloService client) {
String reply = client.sayHi("特蕾莎");
System.out.println("Server said: " + reply);
}
*************************************************************************
然后是复杂数据类型的问题,经过测试,发觉基本数据类型和List都是没有问题的,我的测试方法包括
@WebMethod
String sayHi(@WebParam String name);
@WebMethod
List<Integer> getList(@WebParam List<String> strs);
@WebMethod
List<User> getJavaBean();
但是传递Map时,就出现问题了,所以参照了user's guide,得到如下解决办法
测试某个方法的参数和返回值都是Map类型
@WebMethod
@XmlJavaTypeAdapter(MapAdapter.class)
Map<String, String> getMap(@WebParam @XmlJavaTypeAdapter(MapAdapter.class) Map<String, String> map);
MapAdapter是我自己写的用於數據類型轉換的适配器类,代码如下
public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {
@Override
public MapConvertor marshal(Map<String, Object> map) throws Exception {
MapConvertor convertor = new MapConvertor();
for(Map.Entry<String, Object> entry:map.entrySet()){
MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);
convertor.addEntry(e);
}
return convertor;
}
@Override
public Map<String, Object> unmarshal(MapConvertor map) throws Exception {
Map<String, Object> result = new HashMap<String,Object>();
for(MapConvertor.MapEntry e :map.getEntries()){
result.put(e.getKey(), e.getValue());
}
return result;
}
}
MapConvertor.java Map格式转换类
@XmlType(name = "MapConvertor")
@XmlAccessorType(XmlAccessType.FIELD)
public class MapConvertor {
private List<MapEntry> entries = new ArrayList<MapEntry>();
public void addEntry(MapEntry entry){
entries.add(entry);
}
public static class MapEntry{
public MapEntry() {
super();
}
public MapEntry(Map.Entry<String,Object> entry) {
super();
this.key = entry.getKey();
this.value = entry.getValue();
}
public MapEntry(String key,Object value) {
super();
this.key = key;
this.value = value;
}
private String key;
private Object value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
public List<MapEntry> getEntries() {
return entries;
}
}
经过这个MapAdapter,算是完成了Map类型的数据传递
接下来,就是更为复杂的一点的这种情况了:List<Map<String,Object>>
这个情况实在不太好办,目前偶也没有找到更好的办法,偶只能这样做
@WebMethod
List<MapConvertor> getListMap(List<MapConvertor> listmap);
就是把MapConvertor当成Map来使,但偶觉得这不是一个很妥善的办法。
其实偶觉得,WebService里应该尽量减少使用javabean对象进行传输
一个JavaBean可以转换成一个Map
一个包含多个JavaBean的List可以转换成一个包含多个Map的List
所以如果对Map支持得好的话,就应该多用Map和List来实现数据传递
当然在调用的时候,也最好能够像Axis一样使用Call来实现无接口调用
这样在Client端就不需要得到Server提供的任何jar了
这样才是最松散耦合的系统
只可惜现在对Map支持得不是很好,最起码在List<Map>时用的方式感觉不太好
不知道各位GGJJ们是怎么做的呢?
分享到:
- 2009-11-28 23:59
- 浏览 8215
- 评论(7)
- 论坛回复 / 浏览 (6 / 15074)
- 查看更多
相关推荐
spring,cxf,restful发布webservice传递复杂对象,例如List,Map,List<Map>
<groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.1.7</version> </dependency> <!-- CXF webservice --> <dependency> <groupId>org.spring...
<groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <id>generate-sources</id> <phase>g
Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF Apache CXF
Apache CXF 框架是一个比较有前途的开源 Web Services 框架,也是构建 SOA 架构应用的利器。本书采用案例源码和解说形式全面介绍 Apache CXF 框架的功能。 本书共 15 章,大致分为三个部分。第一部分介绍关于 SOA 和...
2013版的 <基于Apache CXF构建SOA应用> 源码 Apache CXF是一个开放源码的Web服务框架,提供了一个易于使用,用于开发Web Services标准为基础的编程模型。本书主要介绍Apache CXF在构建SOA架构各个方面的应用说明和...
apache cxf 2.1.3 的用户手册
CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First...
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CXFService</servlet-name> <url-pattern>/*</url-pattern> </servlet-...
详细的从入门到精通, 手把手的教你做WEB SERVICE 该资源借花献佛,是一个高手写的,我在这里借花献佛,推广推广,让大家多一个学习的机会,吃水不忘挖井人,轻大家也谢谢写该文档的高手
Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。
apache cxf 3.1.8 java web service 开源框架
CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First...
Apache CXF Web Service Development
Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且...
apache-cxf 2.2.8 支持webservice 反正生成服务端代码,附带一个文本文件。希望有需要的小伙伴可以下载来看。
apache cxf 一个helloworld的例子
Apache CXF Web Service Development Developing+Web+Services+with+Apache+CXF+and+Axis2+(3rd+Edition)
java通过cxf实现webservice所需jar包。java通过cxf实现webservice所需jar包。