开发者社区> 问答> 正文

camel中发布webservice的问题

camel自带的例子:camel-example-cxf-tomcat

运行OK。

但是把WebService接口方法的返回值由对象改为List, 当然,实现中也调整为返回List。

但执行错误: Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: org.apache.camel.example.cxf.incident.OutputReportIncident cannot be cast to java.util.List

同样的,含有List返回值的WebService,如果使用CXF发布和实现,执行正常。 
<jaxws:endpoint id="foo" implementorClass="my.FooImpl" address="/foo" /> 

但是调整为camel发布的方式: 
<bean id="fooImpl" class="my.FooImpl"/> 
<camelContext xmlns="http://camel.apache.org/schema/spring"> 
  <route> 
    <from uri="cxf:/foo?serviceClass=my.IFoo"/> 
    <to uri="bean:fooImpl"/> 
  </route> 
</camelContext> 

就会出现cannot be cast to java.util.List的错误。 
如果把List返回方式改为普通对象,就执行正常。 

有人帮看一下吗? 
多谢!
问题补充:错误信息发错了:应该是下面的: 
Caused by: java.lang.ClassCastException: org.apache.camel.example.cxf.incident.OutputReportIncident cannot be cast to java.util.List 
at org.apache.camel.example.cxf.incident.jaxws_asm.ReportIncidentResponse_WrapperTypeHelper1.createWrapperObject(Unknown Source) 
at org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:101)
问题补充:难道是camel CXF Component组件的BUG吗?
问题补充:代码在:http://dl.iteye.com/topics/download/738cb55e-531d-3852-b00b-86cbe1e43fc2 
因为上传文件太大,我去掉了Spring的JAR包。 
问题补充:改动总共3处: 
1、IncidentService类: 
    List<OutputReportIncident> reportIncident(InputReportIncident input); 
2、CamelRoute类: 
    List result = new ArrayList(); 
    result.add(output); 
    exchange.getOut().setBody(result); 
3、CamelRouteClient类: 
    OutputReportIncident out = client.reportIncident(input).get(0); 
问题补充:有点奇怪的是,错误信息变成了(??): 

java.lang.IllegalArgumentException: Part {http://incident.cxf.example.camel.apache.org/}return should be of type [Lorg.apache.camel.example.cxf.incident.OutputReportIncident;, not org.apache.camel.example.cxf.incident.OutputReportIncident 
at org.apache.cxf.jaxb.io.DataWriterImpl.checkPart(DataWriterImpl.java:221)

展开
收起
长安归故里. 2020-01-13 17:12:27 1728 0
1 条回答
写回答
取消 提交回答
  • 我试了下,你这个错误不是camel,也不是cxf的,而是jaxb的错误。jaxb解析的时候,是需要被解析对象添加了jaxb的注解:(@XmlRootElement) 如果你想返回List,可以把list的值放到对象中,然后通过对象获取list列表。 这是我的测试代码,如下:

    Java代码 收藏代码

    OutputReportIncident output = new OutputReportIncident();  
          output.setCode("OK;");  
          List<OutputReportIncident> result = new ArrayList<OutputReportIncident>();   
          result.add(output);   
            
          JAXBContext context;  
    try {  
        context = JAXBContext.newInstance(ArrayList.class);  
           Marshaller marshaller = context.createMarshaller();  
           marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");  
           marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);  
           marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);  
           marshaller.marshal(result, new File("d:/test.xml"));  
    } catch (JAXBException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }
    
    

    这样的代码运行错误信息为: unable to marshal type "java.util.ArrayList" as an element because it is missing an @XmlRootElement annotation]

    而cxf是封装了这样的错误

    2020-01-13 17:12:48
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载