我试图使用MTOM + XOP在Service中返回一个byte[],但是当编组结果时,它会抛出一个带有消息的SAXParseException:
3.1.2:元素'dataHandler‘是一个简单的类型,因此它必须没有元素信息项子元素。
似乎在编写了XOP标记之后,验证器会遇到它而不是它所期望的byte[]内容,并抛出一个具有致命级别的SAXParseException,从而停止该进程。
我在用:
提前感谢
发布于 2016-07-28 14:29:19
我为我的处境找到了两个解决办法:
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());
}
}对于封送器,我正在搜索标识情况的条件,因为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;
}
}激活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()));
}
}发布于 2016-07-26 21:33:36
这不是SAAJ的问题,而是Spring的问题。这是因为Spring将XOP编码的消息传递给架构验证器,后者不理解XOP。最终问题在于Spring没有一个定义良好的XOP/MTOM处理模型,正如我在这篇文章中所解释的那样。
https://stackoverflow.com/questions/38596474
复制相似问题