Spring Integration Web Service - Jaxb2Marshaller - 如何使用SAX Parser?

时间:2017-01-11 04:38:58

标签: jaxb spring-integration sax spring-ws

我在Spring Integration中使用Jaxb2Marshaller。我有一个入站网关Web服务,当有人调用它时,它会自动解析为JAXB生成的类。

但是当我调试源代码时,我看到Jaxb2Marshaller使用DOM。我认为它将使用SAX将XML数据绑定到Java对象中,SAX更快。为什么Jaxb2Marshaller默认使用DOM?如何配置它以使用SAX?

我检查了文件

  

在   unmarshaller需要Source的一个实例。如果消息有效内容不是Source的实例,   将尝试转换。目前String,File和org.w3c.dom.Document有效负载是   支持的。注入a的实现也支持自定义转换为Source   SourceFactory。   注意   如果未明确设置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());
        }
    }

所以,最后一个问题是我可以配置使用带有SAX的JAXB的Spring Integration Web Service吗?我错过了什么吗?

以下是我的配置:

<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 Nguyen

2 个答案:

答案 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);
    }
}

答案 1 :(得分:0)

尝试使用名称AxiomSoapMessageFactory配置MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME bean。

默认情况下,SaajSoapMessageFactory在解组前完成此操作:

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

其中Axiom基于STaX:

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

class StaxSource extends SAXSource {