【问题标题】:Call web service from Camel从 Camel 调用网络服务
【发布时间】:2012-10-30 12:21:57
【问题描述】:

我想从 Camel 调用网络服务。但是每次调用该服务时我都会收到 null 。 你能帮我找到解决办法吗?

该服务在 tomcat 上运行,我可以使用soapUI 对其进行测试。这是来自 SoapUI 的请求。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:hel="http://helloworld.localhost">
    <soapenv:Header/>
       <soapenv:Body>
          <hel:HelloWorldRequest>
               <hel:input>Pavel</hel:input>
          </hel:HelloWorldRequest>
       </soapenv:Body>
    </soapenv:Envelope>

并且响应返回 Hello Pavel。 我按照 CamelInAction 指南创建了合同优先的 Web 服务。 我能够运行读取文件并将其发送到 Web 服务的路由。

路由代码如下。

public class FileToWsRoute extends RouteBuilder {
public void configure() { 
    from("file://src/data?noop=false")
    .process(new FileProcessor())
    .to("cxf:bean:helloWorld");
    }

}

FileProcessor 类如下所示:

public class FileProcessor implements Processor {

public void process(Exchange exchange) throws Exception {

    System.out.println("We just downloaded: " 
            + exchange.getIn().getHeader("CamelFileName"));
    String text = 
    "<?xml version='1.0' ?>" 
    +"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:hel=\"http://helloworld.localhost\">"
    +"<soapenv:Header/>"
    +   "<soapenv:Body>"
    +     " <hel:HelloWorldRequest>"
    +        " <hel:input>WhatsUP</hel:input>"
    +     " </hel:HelloWorldRequest>"
    +   "</soapenv:Body>"
    +"</soapenv:Envelope>";

    exchange.getIn().setBody(text);
}
}

在下一个版本中,我想通过 cxf-codegen-plugin 生成的对象(HalloWorld.java、HelloWorldImpl.java、HelloWorldRequest.java、HelloWorldResponse.java、HelloWorldService.java、ObjectFactory.java、package- info.java)。

在 camel-cxf.xml 我有:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:cxf="http://camel.apache.org/schema/cxf"
   xsi:schemaLocation="
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://camel.apache.org/schema/cxf 
     http://camel.apache.org/schema/cxf/camel-cxf.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-extension-http-jetty.xml"/>

  <cxf:cxfEndpoint id="helloWorld"
               address="http://localhost:8080/ode/processes/HelloWorld"
               serviceClass="localhost.helloworld.HelloWorld"
               wsdlURL="wsdl/HelloWorld.wsdl"/>
</beans>

要读取来自我正在使用此路由的 Web 服务的响应。

public class WsToQueueRoute extends RouteBuilder {
    public void configure() { 
    from("cxf:bean:helloWorld")
    .to("seda:incomingOrders")
    .transform().constant("OK");
    }

}

最后一个路由从 seda 获取数据...

public class QueueToProcessRoute extends RouteBuilder {
public void configure() { 
    from("seda:incomingOrders")
    .process(new PrintResult());
    }

}

...并打印结果。

public class PrintResult implements Processor {

public void process(Exchange exchange) throws Exception {

    System.out.println("Data received: " 
            + exchange.getIn().getBody(String.class));
}

}

执行的输出是: 收到的数据:空

我希望有一些可以用 cxf 对象解析的 XML 文件。你能帮我找出问题吗?

谢谢

帕维尔

【问题讨论】:

    标签: web-services apache cxf apache-camel


    【解决方案1】:

    这个例子的问题在于 FileProcessor 和 PrintResult 类。我还简化了示例,所以我现在只使用一个路由 FileToWsRoute。

    public class FileToWsRoute extends RouteBuilder {
    public void configure() { 
        from("file://src/data?noop=true")
        .process(new FileProcessor())
        .to("cxf:bean:helloWorld")
        .process(new PrintResult());
        }
    }
    

    FileProcessor 已更改为这个。

    public class FileProcessor implements Processor {
    
    public void process(Exchange exchange) throws Exception {
            HelloWorldRequest hs = new HelloWorldRequest();
            hs.setInput("Pavel");
            exchange.getOut().setBody(hs);
        }
    }  
    

    PrintProcessor 已更改为此。

    public class PrintResult implements Processor {
    public void process(Exchange exchange) throws Exception {
        MessageContentsList msgList = (MessageContentsList) exchange.getIn().getBody();
        HelloWorldResponse resp = (HelloWorldResponse) msgList.get(0);
        String result = resp.getResult();       
           System.out.println("Data received: " + result);
        }
    
    }
    

    我认为这对于在骆驼和网络服务方面苦苦挣扎的其他人来说是一个很好的例子。

    【讨论】:

    • 将此代码作为示例项目分享到 github 或 bitbucket 等上可能是个好主意。
    • @mr.pohl 这个 HelloWorldRequest 是什么?一个处理器还是只是一个 SOAP 信封?您能否提供一个相同的文件上传示例?
    【解决方案2】:

    问题可能与发送到您的process 方法的数据格式有关。我会尝试将camel cxf 属性添加到端点,如下所示:

    <cxf:properties>
        <entry key="dataFormat" value="POJO"/> 
    </cxf:properties>
    

    通过将数据格式更改为POJO,您应该会收到您的消息。所以你的camel cxf 端点应该是这样的:

      <cxf:cxfEndpoint id="helloWorld"
                   address="http://localhost:8080/ode/processes/HelloWorld"
                   serviceClass="localhost.helloworld.HelloWorld"
                   wsdlURL="wsdl/HelloWorld.wsdl">
        <cxf:properties>
            <entry key="dataFormat" value="POJO"/> 
        </cxf:properties>
      </cxf:cxfEndpoint>
    

    我曾经遇到过类似的问题,这解决了我的问题,但我在 Spring 中使用骆驼而不是 java 类。

    如果这不起作用,请尝试将参数:?dataFormat=POJO 添加到您的路线中,如下所示:

    from("cxf:bean:helloWorld?dataFormat=POJO")
    

    【讨论】:

    • 感谢您的回答。这不是问题,但另一方面它不会造成任何伤害。请参阅下面的工作示例。
    • 谁能告诉我如何运行这个例子?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多