Ответ SOAP неправильно десериализовался как нулевой в CXF + Простой интерфейс + привязка данных Aegis
Я пишу клиент для веб-службы SOAP. Я использую библиотеку CXF. С простым интерфейсом. И привязка данных Aegis. Сервер предоставляет интерфейс Java (названный MediaService) для веб-методов, и я импортирую этот интерфейс в клиентский проект. Затем я использую файл MediaService.aegis.xml, чтобы предоставить имена для параметров метода (чтобы они не назывались и при сериализации запроса).
Вот код, который я использую на клиенте:
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setDataBinding(new AegisDatabinding());
factory.setServiceClass(MediaService.class);
factory.setAddress(urlMediaServer);
MediaService service = (MediaService) factory.create();
final List<Reference> listeReferences = service.sendMedia(bu, media);
Интерфейс сервиса выглядит так:
public interface MediaService
{
public List sendMedia(String bu, Media media) throws Exception;
}
Я включил ведение журнала потока XML, чтобы видеть поток XML, отправляемый на сервер, и поток, который он возвращает.
Вот потоки:
Запрос:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:sendMedia xmlns:ns1="http://service.soclemedia.mycompany.com/">
<ns1:bu>sc_phx</ns1:bu>
<ns1:media>
<ns2:productId xmlns:ns2="http://bo.soclemedia.mycompany.com">TEST_CODE</ns2:productId>
<ns2:mediaName xmlns:ns2="http://bo.soclemedia.mycompany.com">test.png</ns2:mediaName>
</ns1:media>
</ns1:sendMedia>
</soap:Body>
</soap:Envelope>
Отклик:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<sendMediaResponse xmlns="http://service.soclemedia.mycompany.com">
<out xmlns="http://service.soclemedia.mycompany.com">
<ns1:Reference xmlns:ns1="http://bo.soclemedia.mycompany.com">
<subType xmlns="http://bo.soclemedia.mycompany.com">standard</subType>
<typeMedia xmlns="http://bo.soclemedia.mycompany.com">photo</typeMedia>
</ns1:Reference>
<ns1:Reference xmlns:ns1="http://bo.soclemedia.mycompany.com">
<subType xmlns="http://bo.soclemedia.mycompany.com">standard</subType>
<typeMedia xmlns="http://bo.soclemedia.mycompany.com">photo</typeMedia>
</ns1:Reference>
</out>
</sendMediaResponse>
</soap:Body>
</soap:Envelope>
Служба вызывается, она отвечает, и клиент получает правильный ответ. Но в клиенте строка service.sendMedia(bu, media), вызывающая вызов веб-службы, возвращает ноль. Что-то не так с десериализацией ответа. У вас есть представление о том, что пошло не так и как это исправить?
С наилучшими пожеланиями.
ОБНОВИТЬ:
Я забыл упомянуть, что когда я вызываю этот метод:
MediaService service = (MediaService) factory.create();
Я получаю эту ошибку:
INFO: Creating Service {http://service.soclemedia.mycompany.com/}MediaService from class com.mycompany.soclemedia.service.MediaService
24 nov. 2011 15:18:37 org.apache.cxf.aegis.type.XMLTypeCreator <clinit>
INFO: Could not set aegis schema. Not validating.
java.lang.UnsupportedOperationException: This parser does not support specification "null" version "null"
at javax.xml.parsers.DocumentBuilderFactory.setSchema(DocumentBuilderFactory.java:489)
at org.apache.cxf.aegis.type.XMLTypeCreator.<clinit>(XMLTypeCreator.java:125)
at org.apache.cxf.aegis.AegisContext.createRootTypeCreator(AegisContext.java:122)
at org.apache.cxf.aegis.AegisContext.createTypeCreator(AegisContext.java:111)
at org.apache.cxf.aegis.AegisContext.initialize(AegisContext.java:153)
at org.apache.cxf.aegis.databinding.AegisDatabinding.initialize(AegisDatabinding.java:229)
at org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:438)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:501)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:241)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:101)
at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:90)
at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:153)
...
Вот мой cxf.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
</beans>
ОБНОВЛЕНИЕ 2:
А вот мой MediaService.aegis.xml:
<mappings>
<mapping>
<method name="sendMedia">
<parameter index="0" mappedName="bu"/>
<parameter index="1" mappedName="media"/>
<return-type componentType="com.mycompany.soclemedia.bo.Reference" />
</method>
</mapping>
</mappings>
1 ответ
Просто мысль:
В одном из проектов, который я недавно обнаружил, веб-сервис CXF работал нормально при локальном запуске в Jetty, тогда как все коллекции верхнего уровня десериализовались как нулевые при запуске в контейнере Weblogic.
По-видимому, это было вызвано известной ошибкой в JAXB (ссылка не нужна, извините), и обходной путь должен был обернуть коллекцию следующим образом:
public class Wrapper
{
private List<Reference> references;
...
}
и вместо этого сделайте так, чтобы веб-сервис работал с этим объектом в сети.
Я надеюсь, что это может относиться и к вашей проблеме, если не удача в любом случае:-)
/ Anders /