SAAJ与MTOM+XOP兼容吗



我正试图使用MTOM+XOP在Spring Web Service中返回一个byte[],但当整理结果时,它会抛出一个SAXParseException,并显示消息:

3.1.2:元素"dataHandler"是一个简单的类型,因此它必须没有元素信息项[childred]。

似乎在编写XOP标记后,验证器会遇到它,而不是它所期望的byte[]内容,并抛出一个具有FATAL级别的SAXParseException来停止进程。

我正在使用:

  • JDK 1.7
  • SAAJ 1.3
  • 肥皂1.1
  • 春季4.1.4.发布
  • 弹簧WS 2.2.0.释放

提前感谢

我找到了两种解决方法:

  1. 未将xmlschema设置为marshaller。

  2. ValidationEventHandler设置为可跳过XOP失败的编组器。

这是将ValidationEventHandler设置为跳过XOP故障的编组器的示例:

抽象超类:

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只有Object集,它可以是任何对象。

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;
  }
}

激活MTOM并添加两个事件处理程序的org.springframework.oxm.jaxb.Jaxb2Marshaller子类:

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()));
  }
}

这不是SAAJ的问题,而是Spring WS的问题。这是由于SpringWS将XOP编码的消息传递给模式验证器,而模式验证器不理解XOP。最终的问题是,正如我在本文中所解释的,SpringWS没有一个定义良好的XOP/MTOM处理模型。

相关内容

  • 没有找到相关文章

最新更新