这两天在做使用CXF框架的时候遇到了一个传输复杂对象的问题,问题如下:
背景:
那这里的o可能是WebServiceResult,和WebServiceResult内部的各个实例变量(是"循环遍历"WebServiceResult内的所有对象,调用getBeanInfo方法)
主要子类有:
首先,我定义一个JavaBean WebServiceResult 里面有这么几个属性:private boolean success =false;private Map<String,List<Topic>> result = new HashMap<String,List<Topic>>();private ArrayList<Topic> topics ;private transient String resultCode;其中,Map我暂且叫做“复杂对象” 因为 一个map里面,装了一个list,而list里面又装了一个自己的JavaBean Topic(活动信息)接口调用完成后会用WebServiceResult 封装调用结果返回给客户端用客户端调用该接口后发现,result属性值为null,但是,对服务端的debug排除了没有set值的情况,查看后还发现了服务端抛出了"class XXX nor any of its super class is known to this context" 的异常
排查过程:
1. 从异常内容可以看到CXF内部应该有至少一个上下文环境存放当前接口涉及到的Java类的class信息
2. 通过异常定位到CXF内部,debug后理解上下文环境,可以看到,异常出自这里:
fatal在调用的时候就写死了为true,当bi为null时,就会报出异常,再看getBeanInfon内部:
o对象既是需要将数据绑定到xml文件上的对象,在这里是o是接口调用后返回的对象
比如:接口方法签名为:
那这里的o可能是WebServiceResult,和WebServiceResult内部的各个实例变量(是"循环遍历"WebServiceResult内的所有对象,调用getBeanInfo方法)
回到getBeanInfon方法,程序会从beanInfoMap中取出预置好的将Bean映射到xml上的对象JaxBean(这里先卖个弯子,后面会说到它怎么来的)
如果beanInfoMap里没有这个class对应的JaxBeanInfo对象,就会return一个null,导致了异常的报出。
几个疑问:
1. JaxBeanInfo是做什么的?
JaxBeanInfo里封装了对大部分Java类映射方式,即,怎么把数据映射到XML上主要方法有:
主要子类有:
2. beanInfoMap是做什么的?
我的理解是:在服务端初始化的时候,CXF会去看这个接口里,参数和返回值的类型,并根据类型生成相应的JaxBeanInfo对象放在map里面,
这里好理解,就是等接口被调用时知道 "怎么" 把返回值 映射到XML上,传给客户端。
3. 既然是在服务端初始化的时候去遍历方法签名,将涉及的Bean的相对应的解析对象放到Map中,又怎么会在接口返回的时候找不到解析该Bean的JaxBean呢?
回到这段代码:
再看他的上层调用:
问题就在这里,如WebServiceResult 中的声明:private Map<String,List<Topic>> result = new HashMap<String,List<Topic>>();
CXF在初始化的时候,“登记”的是List,保存的class信息为java.util.List 而我们在时间使用的时候,通常是这样,
List<Topic> topics = new ArrayList<Topic>() 这个时候,topics的class信息是:java.util.ArrayList
当接口调用返回的时候,上图中的 : boolean asExpected = chlid.getCalss() == expected.jaxbType;
就是那 java.util.List == java.util.ArrayList 导致比较失败,最终进入grammar.getBeanInfo去拿jaxBeanInfo的时候,
因为”登记“的是java.util.List的JaxBeanInfo而不是java.util.ArrayList,导致拿不到jaxBeanInfo,最后报出异常。
解决方法
解决方法非常简单,当我们在声明接口参数和返回值的时候,别使用到接口或者抽象类 比如java.util.List等
而是直接写成他们的实现类或者子类 保证实际调用方法的时候的class信息和方法声明的class信息是一致的就可以了,因此,WebServiceResult 改为如下后,可以正常传输
private boolean success =false;
private Map<String,ArrayList<Topic>> result = new HashMap<String,ArrayList<Topic>>();
private ArrayList<Topic> topics ;
private transient String resultCode;
ps: 网上有说CXF不支持Map等复杂对象的传输,经过测试,在Jaxb 2.1(CXF 2.2 版本依赖)版本是不存在该问题的。
未解决的问题:
1. Map<String,ArrayList<Topic>> 格式的result传输不会报错,但是map中的list的值会"丢失",即,客户端收到的是空的List(单独一个List传输是不会的)。
遗留下来的问题,有空再解决下,大家有知道的也请楼下回复
相关推荐
总的来说,CXF服务端对象文件支持断点传送是一项重要的特性,它提高了大文件传输的效率和可靠性,同时展示了CXF在处理复杂数据交换和文件操作方面的强大能力。开发者可以通过学习和研究这个示例,更好地理解和利用...
第一天: 什么是webservice? 从案例(便民查询网站... 测试jaxws传输复杂对象类型 CXF开发webservice: CXF入门程序 Spring+cxf整合(重点) CXF发布rest的webservice。(重点) 综合案例: 实现便民查询网站
3. **数据绑定**:CXF提供了数据绑定框架,如JAXB(Java Architecture for XML Binding)用于XML到Java对象的转换,简化了数据交换过程。 4. **WS-*规范支持**:CXF实现了诸如WS-Security、WS-Addressing、WS-...
3. **数据绑定**:CXF提供了多种数据绑定机制,如JAXB(Java Architecture for XML Binding)用于XML到Java对象的映射,以及 JiBX 和 Aegis 用于非标准对象到XML的转换。 4. **协议栈**:CXF支持多种传输协议,如...
CXF不仅仅是SOAP(简单对象访问协议)和RESTful(Representational State Transfer)服务的实现,还提供了丰富的功能,如WS-*(Web服务扩展)规范支持、客户端和服务端的代码生成工具、多种传输协议支持以及与Spring...
- 数据绑定:如JAXB,用于XML对象和Java对象之间的转换。 - 安全性:支持基本认证、SSL、WS-Security等。 - 传输和绑定:如HTTP、HTTPS、FTP等传输方式,以及XML/HTTP、SOAP/HTTP绑定。 - 扩展:包括Spring整合、...
- 如何利用CXF实现复杂的安全策略和消息传递模式。 - 如何将CXF集成到现有的Java EE应用服务器中,如Tomcat、Jetty等。 - 如何使用CXF与其他Java框架(如Spring)配合,实现松耦合的Web服务解决方案。 总之,Apache...
3. **数据绑定**:CXF提供了JAXB(Java Architecture for XML Binding)和Data Binding API(DBAPI)来将XML数据自动映射到Java对象,简化了数据交换过程。 4. **WSDL第一**:CXF支持从WSDL文件自动生成服务端和...
对于文件下载,你可以返回一个包含文件内容的`StreamingOutput`对象,让CXF负责将数据流传输到客户端。 除了这些基础功能,CXF还支持高级特性,如安全性(例如WS-Security)、事务处理、错误处理和性能优化。例如,...
- **Bus**:CXF的核心是Bus组件,它管理服务的生命周期,处理消息传输,并提供了插件机制以扩展其功能。 - **Endpoint**:表示Web服务的实例,它定义了服务如何接收和发送消息。 - **DataBinding**:负责将XML...
综上所述,这个CXF Webservice示例工程涵盖了Spring集成、Web服务安全、大文件传输优化以及不同类型数据的处理,是学习和实践CXF框架的理想起点。通过对这些知识点的深入理解和实践,开发者能够更好地掌握如何在实际...
除了这些核心JAR文件,一个完整的CXF客户端可能还需要其他依赖,例如JAXB(Java Architecture for XML Binding)用于XML和Java对象之间的转换,或者log4j或slf4j用于日志记录。然而,描述中提到的"告别找jar包的繁琐...
6. **传输与编码**:CXF允许自定义传输层和消息编码,以适应不同的网络环境和性能需求。 7. **测试工具**:CXF包含一个强大的测试框架,如CXF TestSuite,帮助开发者进行集成测试和端到端测试,确保服务的正确性和...
4. **丰富的协议支持**:CXF不仅支持HTTP,还支持JMS、SMTP等多种传输协议,可以处理MTOM(Message Transmission Optimization Mechanism)和SwA(Soap with Attachments)等复杂的消息交换模式。 5. **集成其他...
这个压缩包"apache-cxf-2.7.6"包含了该版本的所有组件和资源,使得开发者能够方便地实现基于SOAP(简单对象访问协议)和RESTful(表述性状态转移)的Web服务。 CXF这个名字是"CXF = XFire + Celtix"的合并,这两个...
6. **拦截器和管道**:CXF的拦截器机制允许在服务调用前后插入自定义逻辑,而管道则允许对消息进行复杂处理和转换。 7. **Spring框架集成**:CXF可以很好地与Spring框架结合,使得服务的配置和管理变得更加容易。 ...
- **pom.xml**:如果CXF使用Maven构建,此文件是项目对象模型(Project Object Model),定义了项目依赖和构建指令。 通过研究和使用"apache-cxf-3.1.11",开发者可以深入了解Web服务的实现细节,学习如何使用CXF...
- **数据绑定**:帮助将XML消息自动映射到Java对象,反之亦然,减少手动处理XML的复杂性。 - **错误处理**:提供异常处理机制,便于捕获和处理服务调用中的错误。 4. **使用CXF工具类的步骤** - **添加依赖**:...
CXF 支持 JAXB(Java Architecture for XML Binding)和 Aegis 来进行对象到 XML 和 XML 到对象的转换,简化了数据交换过程。 6. **传输协议和绑定**: - HTTP/HTTPS:CXF 支持标准的 HTTP 和安全的 HTTPS 协议。...
- **cxfConnection**:这个名字暗示这可能是一个关于CXF连接配置的文件,可能包含了CXF与Spring集成的具体配置,例如服务的URL、认证信息、传输协议等。 - **cxfConsumer**:此文件名可能指的是CXF消费者,即...