CXF:通过现有的Servlet传输提供分离的端点

时间:2011-11-09 08:21:33

标签: jetty cxf endpoint ws-addressing ws-reliablemessaging

我有一个应用程序,它使用CXF的Servlet传输和Jetty 6.1提供服务。此应用程序还需要使用外部服务。所有服务都支持WS-Addressing规范(以及WS-RM)。要使用外部服务,我从应用程序运行生成的服务客户端。

问题在于,当我为客户端提供解耦端点时(WS-RM需要此端点通过单独的http连接接收传入消息),CXF运行另一个Jetty服务器实例(尽管Servlet传输的事实) (提供服务)和客户端(消耗一些外部服务)共享相同的总线)。我不需要两个Jetty实例(不是说它们不能在同一个HTTP端口上运行)。

有没有办法可以使用现有的Jetty服务器和Servlet传输提供解耦端点?

到目前为止,我启用了一个解耦端点,如下所示:

Client client = ClientProxy.getClient(port);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
httpConduit.getClient().setDecoupledEndpoint(
     "http://domain.com:port/services/dec_endpoints/TestDecEndpoint");

如果我提供相对路径(“/ dec_endpoints / TestDecEndpoint”,就像通过Servlet传输提供服务一样使用相对路径),HTTP管道不会在SOAP消息的头中指定完整路径,所以这不是工作要么(服务器只是不能发送消息到/ dec_endpoints / TestDecEndpoint)。

1 个答案:

答案 0 :(得分:2)

好的,我自己找到了解决方案。您需要为解耦端点指定相对路径并手动更改消息的寻址属性(在MAPAggregator拦截器之后,因为它设置了解耦目标),以便服务器可以向您的地址发送回复。

所以我们拥有:

  1. 使用相对路径解耦目标:/dec_endpoints/SomeDestination
  2. 带有绝对路径的
  3. <ReplyTo>标头:http://addr.com:port/servlet_path/dec_endpoints/SomeDestination
  4. 以下是如何更改路径的示例:

    public class ReplyToInterceptor extends AbstractPhaseInterceptor<Message>
    {
        public ReplyToInterceptor() {
            super(Phase.PRE_LOGICAL);
            addAfter(MAPAggregator.class.getName());
        }
    
        public void handleMessage(Message message) {
            AddressingProperties maps = ContextUtils.retrieveMAPs(message, false, 
               true);
            EndpointReferenceType replyTo = maps.getReplyTo();
            replyTo.getAddress().setValue(
               "http://address.com:port/servlet_path/dec_endpoints/SomeDestination");
        }
    }