I am using Jaxb2Marshaller
with Spring Integration. I have an inbound gateway web service, when someone call it, it will auto parse into JAXB generated classes.
But when I debug into the source, I see Jaxb2Marshaller
using DOM. I thought it would use SAX as for binding XML data into Java object, SAX is faster. Why Jaxb2Marshaller
use DOM by default ? How can I configure it to use SAX ?
As I checked the document
The unmarshaller requires an instance of Source. If the message payload is not an instance of Source, conversion will be attempted. Currently String, File and org.w3c.dom.Document payloads are supported. Custom conversion to a Source is also supported by injecting an implementation of a SourceFactory. Note If a SourceFactory is not set explicitly, the property on the UnmarshallingTransformer will by default be set to a DomSourceFactory
About SourceFactory
We can see that currently, it only has DomSourceFactory
and StringSourceFactory
. There is no SaxSourceFactory
.
So we can't use SAX with Jaxb2Marshaller
, right ?
Will it have SaxSourceFactory
in the future ? or never ?
The weird thing is when I check Jaxb2Marshaller
, I see the code already handle 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());
}
}
So, the final question is CAN I configure use Spring Integration Web Service with JAXB with SAX ? Am I missed something?
Here is my configurations:
<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>
Thank you and best regards,
Nha Nguyen
Try to configure AxiomSoapMessageFactory
bean with the name MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME
.
By default it is SaajSoapMessageFactory
which does exactly this before unmarshalling:
public Source getPayloadSource() {
SOAPElement bodyElement = SaajUtils.getFirstBodyElement(getSaajBody());
return bodyElement != null ? new DOMSource(bodyElement) : null;
}
where Axiom is based on STaX:
XMLStreamReader streamReader = getStreamReader(payloadElement);
return StaxUtils.createCustomStaxSource(streamReader);
And class StaxSource extends SAXSource {