CXF: предоставление разъединенной конечной точки через существующий транспорт сервлетов
У меня есть приложение, которое предоставляет услуги с использованием транспорта сервлетов CXF и Jetty 6.1. Это приложение также должно использовать внешние сервисы. Все сервисы поддерживают спецификацию WS-Addressing (и WS-RM сверху). Чтобы использовать внешний сервис, я запускаю сгенерированный сервисный клиент из приложения.
Проблема заключается в том, что когда я предоставляю разъединенную конечную точку для клиента (WS-RM нуждается в этой конечной точке для получения входящих сообщений через отдельное соединение http), CXF запускает другой экземпляр сервера Jetty (несмотря на тот факт, что сервер сервлетов (который обеспечивает услуги) и клиент (который потребляет некоторые внешние услуги) совместно использовать одну и ту же шину). Мне не нужны два экземпляра 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 ответ
Хорошо, я нашел решение сам. Вам необходимо указать относительный путь для разъединенной конечной точки и вручную изменить свойства адресации сообщения (после перехватчика MAPAggregator, поскольку он устанавливает разъединенное место назначения), чтобы сервер мог отправлять ответы на ваш адрес.
Итак, что мы имеем:
- отделить пункт назначения, используя относительный путь:
/dec_endpoints/SomeDestination
<ReplyTo>
заголовок с абсолютным путем:http://addr.com:port/servlet_path/dec_endpoints/SomeDestination
Вот пример того, как можно изменить путь:
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");
}
}