У меня есть несколько веб-сервисов SOAP, которые мне нужны для прокси с REST-интерфейсом.Операции API REST будут отображать 1-1 в их эквиваленты SOAP.
Например, для вызова операции operation1
для веб-службы SOAP на http://soapservices/ServiceA его REST-прокси будет POST http://restservices/ServiceA/operation1, с теми же точными объектами привязки данных для аргументов и возвращаемого значения.
Я буду использовать Camel для динамической маршрутизации вызовов REST к соответствующим им конечным точкам SOAP и, возможно, для выполнения некоторой общей предварительной или последующей обработки.
В идеале я хотел бы, чтобы у меня был проект, в котором я просто добавил бы проксированные WSDL, имел бы интерфейсы конечных точек служб JAX-WS, сгенерированные с помощью cxf-codegen-plugin
Maven, и динамический экземпляр CxfEndpoint
bean для служб, использующихфайл свойств, который будет перечислять их.
Для части JAX-RS я нашел повторное использование сгенерированных SEI весьма удобным и использовал SpringJAXRSServerFactoryBean
, который получает программный набор resourceClasses
при запуске приложения, читая перечисленные службы изтот же файл свойств.
У меня есть рабочий проект, но мне нужно вручную изменить сгенерированные SEI, чтобы добавить аннотации JAX-RS (@Path
, @Consumes
, @Produces
, @Post
и т. Д.)просто плохо
Например:
Для этого, и N в общем случае генерирует SEI, как этот:
@WebService(...)
@XmlSeeAlso(...)
@SoapBinding(...)
public interface ServiceAPortType {
@WebMethod(operationName="operation1")
@WebResult(...)
public ResponseObject operation1(@WebParam(...) ParamObject param);
}
У меня есть файл yml:
services:
- service: ServiceA
config:
address: http://soapservices/ServiceA
serviceClass: ServiceAPortType.class
- service: ServiceB
config:
address: http://soapservices/ServiceB
serviceClass: ServiceBPortType.class
Затем зарегистрируйте CxfEndpoint
s для клиентов:
@PostConstruct
public void registerSOAPClients(){
Map<String, Object> values = (Map<String, Object>) ws.getConfig(); // "ws" injected with @ConfigurationProperties
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(CxfEndpoint.class);
for (Map.Entry<String, Object> val : values.entrySet()) {
bdb.addPropertyValue(val.getKey(), val.getValue());
}
beanFactory.registerBeanDefinition(ws.getService(), bdb.getBeanDefinition());
}
Часть JAX-RS, которая требует ручной настройки сгенерированных SEI для добавления @Path
, @Consumes
и различных аннотаций кпозвольте SpringJAXRSServerFactoryBean
использовать их:
@Bean
public SpringJAXRSServerFactoryBean jaxRSfactoryBean() throws ClassNotFoundException {
SpringJAXRSServerFactoryBean bean = new SpringJAXRSServerFactoryBean();
bean.setAddress("/restservices");
bean.setResourceClasses(jaxRSAnnotatedSEIs); // jaxRSAnnotatedSEIs injected from yml serviceClass
return bean;
}
Маршрут Camel довольно прост и выглядит следующим образом:
from("cxfrs:bean:jaxRSfactoryBean?providers=#jsonProvider")
.setHeader("serviceName", getServiceFromURI())
.setHeader("operationName", getOperationFromURI())
.toD("cxf:bean:${header.serviceName}Service?")
.transform().simple("${body.get(0)}")
.marshal().json(JsonLibrary.Jackson)
.end();
Можно ли как-нибудь автоматизировать добавление этих аннотаций, созданных таким образом, из источника?остается неотредактированным или генерируете SEI JAX-RS из SOAP WSDL или существующих SEI JAX-WS?Или, может быть, есть другой более чистый подход?Я открыт для альтернативных подходов, если они не предполагают ручную модификацию сгенерированных источников и полагаются на файлы свойств только для перечисления и настройки служб.