2016-07-26 9 views
2

Ich versuche MTOM + XOP zu verwenden, um ein byte [] in einem Frühlings-Web Service zurückzubringen, wenn Ergebnis Rangier wirft es eine SAXParseException mit Nachricht:Ist SAAJ kompatibel mit MTOM + XOP? aber

cvc-type.3.1.2: Element 'datahandler' ist ein einfacher Typ, also muss es keine Element-Informationseinheit [Kinder] haben.

Es scheint, dass nach dem Schreiben des XOP-Tags der Validator mit dem Inhalt von Byte [] übereinstimmt und eine SAXParseException mit FATAL-Level auslöst, die den Prozess stoppt.

Ich bin mit:

  • JDK 1.7
  • SAAJ 1.3
  • SOAP 1.1
  • Frühling 4.1.4.RELEASE
  • Frühling WS 2.2.0.RELEASE

Vielen Dank im Voraus

Antwort

1

Ive fand zwei Abhilfen für meine Situation:

  1. Nicht die XmlSchema Einstellung Einweiser.

  2. Einstellung eines ValidationEventHandler für den Marshaller, der XOP-Fehler überspringt.

Dies ist ein Beispiel für eine ValidationEventHandler zu Einweiser Einstellung, die XOP Ausfälle überspringt:

Abstrakte Oberklasse:

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

Betonklasse für Unmarshaller:

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

Für Einweiser Ich suche nach der Bedingung, die den Fall identifiziert, weil die ValidationEventLocator haben nur das Objekt gesetzt und es könnte was auch immer sein.

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 Unterklasse, die MTOM aktiviert und fügt beide Event-Handler:

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

Das ist kein Problem mit SAAJ, aber mit Spring-WS. Dies liegt daran, dass Spring-WS die XOP-codierte Nachricht an den Schema-Validator übergibt, der XOP nicht versteht. Letztlich ist das Problem, dass Spring-WS kein genau definiertes Verarbeitungsmodell für XOP/MTOM hat, wie ich in this article erklärt habe.

+0

Dank Andreas, lesen Ive Ihren Artikel. Was mich überrascht, ist, dass dies in Spring-WS kein offenes Thema ist und in Foren nicht sehr kommentiert wird. – leaqui

+0

Dies ist immer noch ein Problem zu diesem aktuellen Datum? –

+0

Ich denke, die Situation ist ziemlich unverändert. Vor einigen Monaten habe ich ein paar Pull-Requests gesendet, um einige der Probleme zu beheben, aber ich habe nie eine Antwort erhalten. Ich denke, das Problem ist, dass Spring-WS kein Community-Projekt ist: Wenn Sie einen Supportvertrag mit Pivotal haben, können Sie Änderungen am Produkt vornehmen, ansonsten viel Glück. –

Verwandte Themen