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
I'm using WebServiceGatewaySupport classes and tried adding a AxiomSoapMessageFactory as Bean to the application context, until I found out that WebServiceTemplate does not load the WebServiceMessageFactory from the application context. So I ended up with adding a constructor:
public class SomeServiceImpl extends WebServiceGatewaySupport implements SomeService {
public SomeServiceImpl(WebServiceMessageFactory messageFactory) {
super(messageFactory);
}
}
and building the service myself with a @Configuration
class:
@Configuration
public class WebServicesConfiguration {
private WebServiceMessageFactory webServiceMessageFactory = new AxiomSoapMessageFactory();
@Bean
public SomeService someService() {
return new SomeServiceImpl(webServiceMessageFactory);
}
}
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 {
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.