2017-01-11 90 views
2

Я использую Jaxb2Marshaller с интеграцией с весной. У меня есть веб-служба входящего шлюза, когда кто-то ее вызывает, он автоматически анализирует классы, сгенерированные JAXB.Spring Integration Web Service - Jaxb2Marshaller - Как я могу использовать SAX Parser?

Но когда я отлаживаю исходный код, я вижу Jaxb2Marshaller с использованием DOM. Я думал, что использовать SAX для привязки данных XML к объекту Java, SAX быстрее. Почему Jaxb2Marshaller использовать DOM по умолчанию? Как настроить его для использования SAX?

Как я проверил документ

unmarshaller требуется экземпляр Источника. Если полезная нагрузка сообщения не является экземпляром источника, будет предпринята попытка преобразования . В настоящее время поддерживаются файлы String, File и org.w3c.dom.Document: . Пользовательское преобразование в источник также поддерживается введением реализации SourceFactory. Примечание Если SourceFactory не установлено явно, то свойство на UnmarshallingTransformer будет по умолчанию устанавливается в DomSourceFactory

О SourceFactory

http://docs.spring.io/spring-integration/api/org/springframework/integration/xml/source/SourceFactory.html

Мы можем видеть, что в настоящее время, это только имеет DomSourceFactory и StringSourceFactory. Нет SaxSourceFactory.

Таким образом, мы не можем использовать SAX с Jaxb2Marshaller, верно?

Будет ли оно иметь SaxSourceFactory в будущем? или никогда?

Странная вещь, когда я проверяю Jaxb2Marshaller, я вижу код уже обрабатывать SAX

XMLReader xmlReader = null; 
    InputSource inputSource = null; 

    if (source instanceof SAXSource) { 
     SAXSource saxSource = (SAXSource) source; 
     xmlReader = saxSource.getXMLReader(); 
     inputSource = saxSource.getInputSource(); 
    } 
    else if (source instanceof StreamSource) { 
     StreamSource streamSource = (StreamSource) source; 
     if (streamSource.getInputStream() != null) { 
      inputSource = new InputSource(streamSource.getInputStream()); 
     } 
     else if (streamSource.getReader() != null) { 
      inputSource = new InputSource(streamSource.getReader()); 
     } 
     else { 
      inputSource = new InputSource(streamSource.getSystemId()); 
     } 
    } 

Итак, последний вопрос CAN настроить с помощью Spring Integration веб-службы с JAXB с SAX? Я что-то пропустил?

Вот мои конфигурации:

<ws:inbound-gateway id="inbound-gateway" request-channel="RequestChannel" reply-channel="ResponseChannel" 
     marshaller="marshaller"  unmarshaller="marshaller" /> 
<int:channel id="RequestChannel" /> 
<int:channel id="ResponseChannel" /> 

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
    <property name="contextPath" value="com.example.webservice.api"/> 
</bean> 

Спасибо и наилучшими пожеланиями,

Nha Нгуен

+0

@lexicore Не могли бы вы мне помочь в этом :-) –

+0

саксофон не быстрее .. . sax часто медленнее из-за всей дополнительной логики приложения, необходимой для пользовательского внедрения ... –

+0

Похоже, у вас есть недоразумение. Вы показываете '', но говорите о 'UnmarshallingTransformer'. Первый полностью делегирует Spring WS 'MarshallingUtils.unmarshal()' –

ответ

0

Попробуйте настроить AxiomSoapMessageFactory компонент с именем MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME.

По умолчанию это SaajSoapMessageFactory, который делает именно это до демаршаллизации:

public Source getPayloadSource() { 
    SOAPElement bodyElement = SaajUtils.getFirstBodyElement(getSaajBody()); 
    return bodyElement != null ? new DOMSource(bodyElement) : null; 
} 

где Аксиома базируется на Stax:

XMLStreamReader streamReader = getStreamReader(payloadElement); 
return StaxUtils.createCustomStaxSource(streamReader); 

И class StaxSource extends SAXSource {

+0

Да, я пытался настроить и успешно^_ ^. Теперь JAXB unmarshalling использует синтаксический анализатор StAX (даже лучше SAX). –

+0

Я думаю, для того, чтобы иметь SAX Source (так JAXB будет звонить SAXParser), мне нужно найти стороннюю библиотеку, у которой getPayloadSource() возвращает SAXSource ^^ Спасибо –

+0

Итак, время, чтобы принять ответ и прочитать внимательно прочитал –

1

я использую классы WebServiceGatewaySupport и попытался добавить AxiomSoapMessageFactory в качестве компонента в контекст приложения, пока не узнал, что WebServiceTemplate делает не загружать WebServiceMessageFactory из контекста приложения. Таким образом, я закончил с добавлением конструктора:

public class SomeServiceImpl extends WebServiceGatewaySupport implements SomeService { 

    public SomeServiceImpl(WebServiceMessageFactory messageFactory) { 
     super(messageFactory); 
    } 
} 

и строительство сервис сам с @Configuration класса:

@Configuration 
public class WebServicesConfiguration { 

    private WebServiceMessageFactory webServiceMessageFactory = new AxiomSoapMessageFactory(); 

    @Bean 
    public SomeService someService() { 
     return new SomeServiceImpl(webServiceMessageFactory); 
    } 
}