2017-01-11 141 views
2

我在Spring Integration中使用Jaxb2Marshaller。我有一個入站網關Web服務,當有人調用它時,它會自動解析到JAXB生成的類中。Spring集成Web服務 - Jaxb2Marshaller - 如何使用SAX解析器?

但是當我調試到源代碼時,我看到使用DOM的Jaxb2Marshaller。我認爲它將使用SAX來將XML數據綁定到Java對象,SAX更快。爲什麼Jaxb2Marshaller默認使用DOM?我怎樣才能配置它使用SAX?

當我檢查的原稿

的 解組需要資源的一個實例。如果消息有效負載不是源的實例,則將嘗試轉換 。目前支持的字符串,文件和org.w3c.dom.Document有效載荷爲 。通過注入SourceFactory的實現也支持自定義轉換爲Source。 注意 如果沒有設置SourceFactory明確,對UnmarshallingTransformer酒店將 被默認設置爲DomSourceFactory

關於SourceFactory

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

我們只看到它目前有DomSourceFactoryStringSourceFactory。沒有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()); 
     } 
    } 

所以,最終的問題是,我可以配置使用Spring集成Web服務與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> 

謝謝你,最好的問候,

芽阮

+0

@lexicore你能幫我在這:-) –

+0

SAX是不是更快.. 。薩克斯通常比較慢,因爲你需要自定義實現的所有額外的應用程序邏輯... –

+0

看起來像你有一些誤解。你顯示'',但是談論'UnmarshallingTransformer'。第一個完全委託給Spring WS'MarshallingUtils.unmarshal()' –

回答

0

嘗試與名稱MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME配置AxiomSoapMessageFactory豆。

默認情況下它是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使用StAX解析器解組(甚至比SAX更好)。 –

+0

我想爲了有SAX源(所以JAXB將調用SAXParser),我需要找到一個第三方庫,它有getPayloadSource()返回一個SAXSource ^^ 謝謝 –

+0

所以,接受答案和閱讀手冊仔細 –

1

我使用WebServiceGatewaySupport類和嘗試添加一個AxiomSoapMessageFactory作爲Bean到應用程序上下文,直到我發現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); 
    } 
}