【问题标题】:Spring Integration Web Service - Jaxb2Marshaller - How I can use SAX Parser?Spring 集成 Web 服务 - Jaxb2Marshaller - 我如何使用 SAX 解析器?
【发布时间】:2017-01-11 04:38:57
【问题描述】:

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

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

当我检查文档时

unmarshaller 需要一个 Source 实例。如果消息负载不是 Source 的实例, 将尝试转换。目前 String、File 和 org.w3c.dom.Document 有效载荷是 支持的。通过注入一个实现也支持到源的自定义转换 源工厂。 笔记 如果没有明确设置 SourceFactory,则 UnmarshallingTransformer 上的属性将 默认设置为 DomSourceFactory

关于源工厂

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 Integration Web Service 和 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>

谢谢你和最好的问候,

芽原

【问题讨论】:

  • @lexicore 你能帮我吗:-)
  • sax 并不快...sax 通常较慢,因为您需要自定义实现所有额外的应用程序逻辑...
  • 看来你有什么误解。你显示&lt;ws:inbound-gateway&gt;,但谈论UnmarshallingTransformer。第一个完全委托给 Spring WS MarshallingUtils.unmarshal()
  • @Artem Bilan,我的意思是在 中,我们可以配置解组器,但我们无法配置解组器将使用哪种技术(SAX 或 DOM 或 StAX)。文档说我们可以注入一个 SourceFactory,Spring Integration 会使用它,但是还没有 SaxSourceFactory(只有 DomSourceFactory、StringSourceFactory)。那么我们如何强制 JAXB Unmarshaller 使用 SAX 呢?
  • 您确定该文档是关于 WS 的吗?当您将SourceFactory 注入&lt;int-ws:inbound-gateway&gt; 时,请给我看一个样本。为什么我的回答对你来说还不够?

标签: jaxb spring-integration sax spring-ws


【解决方案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);
    }
}

【讨论】:

    【解决方案2】:

    尝试使用名称MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME 配置AxiomSoapMessageFactory 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 {

    【讨论】:

    • 是的,我试过配置成功^_^。现在 JAXB 使用 StAX 解析器解组(甚至比 SAX 更好)。
    • 我想为了有 SAX Source(所以 JAXB 会调用 SAXParser),我需要找到一个第三方库,让 getPayloadSource() 返回一个 SAXSource ^^ 谢谢
    • 我读了很多次但不明白 util 再次阅读你的答案:-(智商有限:D
    • 是的。我认为混淆的发生是因为 WS 项目使用相同的 OXM 基础。
    • 但是,是的,如果答案是正确的,你应该接受帮助其他人轻松找到解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 2011-06-17
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 2014-02-20
    相关资源
    最近更新 更多