SAAJ是否与MTOM + XOP兼容?

3
我正在尝试在Spring Web服务中使用MTOM + XOP来返回一个byte[],但是当编排结果时,它会抛出一个SAXParseException,其中包含以下消息:
cvc-type.3.1.2:元素“dataHandler”是一个简单类型,因此它必须没有元素信息项[子项]。
似乎在写入XOP标记后,验证器遇到了它,而不是它期望的byte[]内容,并抛出了一个FATAL级别的SAXParseException以停止进程。我使用的是:
JDK 1.7
SAAJ 1.3
SOAP 1.1
Spring 4.1.4.RELEASE
Spring WS 2.2.0.RELEASE
提前感谢。
2个回答

3

对于我的情况,我找到了两种解决方法:

  1. 不将xmlschema设置为marshaller。

  2. 为marshaller设置一个跳过XOP故障的ValidationEventHandler

以下是设置跳过XOP故障的ValidationEventHandler的示例:

抽象超类:

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

abstract class XopAwareValidationEventHandler implements ValidationEventHandler {

  private static final String CVC_TYPE_3_1_2 = "cvc-type.3.1.2";

  private ValidationEventHandler realHandler;

  XopAwareValidationEventHandler(final ValidationEventHandler handler) {
    this.setRealHandler(handler);
  }

  @Override
  public boolean handleEvent(final ValidationEvent event) {
    final boolean result = this.getRealHandler().handleEvent(event);
    if (!result) {
      if (event.getMessage() != null && event.getMessage().startsWith(CVC_TYPE_3_1_2)) {
        return this.isXopEvent(event);
      }
    }
    return result;
  }

  abstract boolean isXopEvent(ValidationEvent validationEvent);

  private ValidationEventHandler getRealHandler() {
    return realHandler;
  }

  private void setRealHandler(final ValidationEventHandler realHandler) {
    this.realHandler = realHandler;
  }
}

用于反序列化的具体类:

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

class XopAwareUnmarshallingValidationEventHandler extends XopAwareValidationEventHandler {

  private static final String XOP_INCLUDE = "xop:Include";

  XopAwareUnmarshallingValidationEventHandler(final ValidationEventHandler handler) {
    super(handler);
  }

  @Override
  boolean isXopEvent(final ValidationEvent validationEvent) {
    final ValidationEventLocator locator = validationEvent.getLocator();
    return locator != null && locator.getNode() != null &&
        locator.getNode().getFirstChild() != null &&
        XOP_INCLUDE.equals(locator.getNode().getFirstChild().getNodeName());
  }
}

对于marshaller来说,我正在寻找能够识别情况的条件,因为ValidationEventLocator只设置了对象,它可能是任何东西。

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationEventLocator;

public class XopAwareMarshallingValidationEventHandler extends XopAwareValidationEventHandler {

  public XopAwareMarshallingValidationEventHandler(final ValidationEventHandler handler) {
    super(handler);
  }

  boolean isXopEvent(final ValidationEvent validationEvent) {
    final ValidationEventLocator locator = validationEvent.getLocator();
    return locator != null && locator.getNode() == null;
  }
}

org.springframework.oxm.jaxb.Jaxb2Marshaller 是一个子类,它可以激活 MTOM 并添加事件处理程序:

import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.springframework.oxm.jaxb.Jaxb2Marshaller;

import XopAwareMarshallingValidationEventHandler;
import XopAwareUnmarshallingValidationEventHandler;

public class XopAwareJaxb2Marshaller extends Jaxb2Marshaller {

  public XopAwareJaxb2Marshaller() {
    this.setMtomEnabled(true);
  }

  protected void initJaxbMarshaller(final Marshaller marshaller) throws JAXBException {
    super.initJaxbMarshaller(marshaller);

    marshaller.setEventHandler(new XopAwareMarshallingValidationEventHandler(marshaller.getEventHandler()));
  }

  protected void initJaxbUnmarshaller(final Unmarshaller unmarshaller) throws JAXBException {
    super.initJaxbUnmarshaller(unmarshaller);

    unmarshaller.setEventHandler(new XopAwareUnmarshallingValidationEventHandler(unmarshaller
        .getEventHandler()));
  }
}

0

这并不是SAAJ的问题,而是Spring-WS的问题。原因是Spring-WS将XOP编码的消息传递给模式验证器,而模式验证器不理解XOP。最终的问题在于,Spring-WS没有针对XOP/MTOM的定义良好的处理模型,我在this article中已经解释了。


谢谢Andreas,我已经阅读了你的文章。让我惊讶的是,这在Spring-WS中并不是一个公开的问题,并且在论坛中也没有得到很多评论。 - leaqui
这个问题到目前为止仍然存在吗? - Tanner Summers
我认为情况基本没有改变。几个月前,我提交了一些拉取请求来开始修复一些问题,但我从未得到回应。我认为问题在于Spring-WS并不是真正的社区驱动项目:如果您与Pivotal有支持合同,那么您将能够将更改纳入产品中,否则祝你好运。 - Andreas Veithen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接