2014-05-20 14 views
5

Wir verwenden JAX-WS in Kombination mit JAXB zum Empfangen und Parsen von XML-Webdienstaufrufen. Es ist alles annotationsbasiert, d. H. Wir bekommen den JAXBContext nie in unserem Code. Ich muss einen benutzerdefinierten ValidationEventHandler auf dem Unmarshaller festlegen, sodass, wenn das Datumsformat für ein bestimmtes Feld nicht akzeptiert wird, wir den Fehler abfangen und etwas Schönes zurück in der Antwort melden können. Wir haben einen XMLJavaTypeAdapter für das fragliche Feld, der die Analyse durchführt und eine Ausnahme auslöst. Ich kann nicht sehen, wie ein ValidationEventHandler auf den Unmarshaller mithilfe der auf Annotation basierenden Konfiguration gesetzt wird, die wir haben. Irgendwelche Ideen?So legen Sie benutzerdefinierten ValidationEventHandler auf JAXB-munmarshaller fest, wenn Sie Anmerkungen verwenden

Hinweis: dieselbe Frage wie this comment, die derzeit unbeantwortet ist.

+0

@BlaiseDoughan Ich hatte gehofft, ich könnte bekommen Meinung darüber, ob das, was wir versuchen, überhaupt möglich ist. Irgendwelche Gedanken? – bobsmells

+0

Jeder? Es scheint, dass diese "Löcher" in der Annotation für einige Features (in Kombination mit dem normalerweise guten Aspekt von Annotationen, die die Bootstrapping-Details von Ihnen wegnehmen) bedeuten, dass Sie Annotationen bei Bedarf nicht wirklich verwenden können diese Funktionen. Ich muss das falsch sehen, da bin ich mir sicher. – bobsmells

+0

Haben Sie Informationen zu diesem Problem erhalten? Mit demselben Problem hier kämpfen. – krtek

Antwort

0

Ich habe in der letzten Woche mit diesem Problem gekämpft und schließlich habe ich eine funktionierende Lösung geschafft. Der Trick ist, dass JAXB nach den Methoden beforeUnmarshal und AfterUnmarshal in dem mit @XmlRootElement annotierten Objekt sucht.

.. 
@XmlRootElement(name="MSEPObtenerPolizaFechaDTO") 
@XmlAccessorType(XmlAccessType.FIELD) 

public class MSEPObtenerPolizaFechaDTO implements Serializable { 
.. 

public void beforeUnmarshal(Unmarshaller unmarshaller, Object parent) throws JAXBException, IOException, SAXException { 
     unmarshaller.setSchema(Utils.getSchemaFromContext(this.getClass())); 
     unmarshaller.setEventHandler(new CustomEventHandler()); 
    } 

    public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) throws JAXBException { 
     unmarshaller.setSchema(null); 
     unmarshaller.setEventHandler(null); 
    } 

Mit dieser Validation:

public class CustomEventHandler implements ValidationEventHandler{ 

     @Override 
     public boolean handleEvent(ValidationEvent event) { 
      if (event.getSeverity() == event.ERROR || 
         event.getSeverity() == event.FATAL_ERROR) 
      { 
        ValidationEventLocator locator = event.getLocator(); 
        throw new RuntimeException(event.getMessage(), event.getLinkedException()); 
      } 
      return true; 
     } 
} 

}

Und das ist die Methode getSchemaFromContext in Ihrer Utility-Klasse erstellt:

@SuppressWarnings("unchecked") 
    public static Schema getSchemaFromContext(Class clazz) throws JAXBException, IOException, SAXException{ 
     JAXBContext jc = JAXBContext.newInstance(clazz); 
     final List<ByteArrayOutputStream> outs = new ArrayList<ByteArrayOutputStream>(); 
     jc.generateSchema(new SchemaOutputResolver(){ 
       @Override 
       public Result createOutput(String namespaceUri, 
         String suggestedFileName) throws IOException { 
       ByteArrayOutputStream out = new ByteArrayOutputStream(); 
       outs.add(out); 
       StreamResult streamResult = new StreamResult(out); 
       streamResult.setSystemId(""); 
       return streamResult; 
       } 
     }); 
     StreamSource[] sources = new StreamSource[outs.size()]; 
     for (int i = 0; i < outs.size(); i++) { 
       ByteArrayOutputStream out = outs.get(i); 
       sources[i] = new StreamSource(new ByteArrayInputStream(out.toByteArray()), ""); 
     } 
     SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     return sf.newSchema(sources); 
    }