2013-07-04 8 views
11

Attualmente sto scrivendo un nuovo set di servizi Web usando JAX-WS, ma ho difficoltà a decidere il modo migliore per convalidare gli input. Posso fare alcune validazioni nelle mie classi di implementazione ma alcuni errori di input falliscono silenziosamente. Ad esempio, i dati di carattere in un elemento numerico generano un numero intero null nell'oggetto JAXB.Come convalidare gli input JAX-WS?

Questi sono i progetti che ho incontrato.

  1. @SchemaValidation
    potrei aggiungere questa annotazione alla classe degli endpoint e JAX-WS prenderò cura della convalida. Questo ha funzionato localmente in Tomcat ma ci sono timori che non funzioni su alcuni server. La mia lamentela principale è che devo rinunciare al controllo su come vengono emessi gli errori nella risposta.

  2. Tutti gli input come stringhe
    Odio questo approccio ma ho visto altri servizi Web in cui tutti gli input sono definiti come stringhe. Questo potrebbe catturare il caso dei dati di carattere in un elemento numerico, poiché potrei controllarlo dove chiamo la nostra API, anche se mancheresti ancora qualsiasi elemento xml con nome errato.

Vorrei davvero che gli errori tornassero nello stesso modo degli errori API piuttosto che come un errore di sapone. Qualche idea? Ho visto alcuni siti che parlano dell'intercettazione della richiesta con un tipo di filtro. Non sono sicuro di come funzionerebbe con risposte diverse per le diverse operazioni.

E.G.

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> 
    <S:Body> 
     <myOperationResponse> 
     <return> 
      <success>false</success> 
      <errors> 
       <error> 
        <code>UNIQUECODE</code> 
        <message>Message text</message> 
       </error> 
      </errors> 
     </return> 
     </myOperationResponse> 
    </S:Body> 
</S:Envelope> 

Forse sto chiedendo troppo ma ho pensato di vedere se mi ero perso qualcosa. TIA.

risposta

7

Trovato questo articolo che spiega un possibile modo.
http://one-size-doesnt-fit-all.blogspot.co.uk/2009/04/jax-ws-schemavalidation-custom-handler.html

Ho restituito il messaggio di errore di analisi nel layout di risposta standard. ho solo bisogno di testarlo funzionerà sulla macchina dei clienti. (Alcune persone dicono che hanno avuto problemi con @SchemaValidation)

+0

L'upvote mi ha appena ricordato questo. Questo è ora in produzione per diversi progetti e non abbiamo avuto problemi. –

7

Se ti ostini a controllo (qualcosa come di solito è necessario rinunciare quando si fa JAX-WS ...) , è possibile implementare un provider e un validatore che convalida uno schema XSD.

Lo schema XSD si occuperà di validare l'input (tipo e potenzialmente enumerazioni, pattern matching, ecc ...)

Per l'attuazione del javax.xml.ws.Provider come SOAP endpoint, creare una classe che sembra

@javax.xml.ws.ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE) 
@javax.xml.ws.WebServiceProvider(
    wsdlLocation = "WEB-INF/wsdl/MyService.wsdl", 
    targetNamespace = "urn-com-acme-webservice", 
    serviceName = "ProcessPurchaseOrderService", 
    portName = "ProcessPurchaseOrderPort" 
) 
public class ProcessPurchaseOrder implements Provider<SOAPMessage> { 


      @override 
    public SOAPMessage invoke(final SOAPMessage request) { 

       //see below  
    } 
} 

A SOAPMessage viene passato al metodo invoke che si aspetta in risposta una risposta valida o SOAPFault racchiusa in un messaggio SOAP;

Per convalidare pagando un XSD, utilizzare un javax.xml.validator:

URL url = this.getClass().getResource(xsdSchemaLocation); 

    String language = XMLConstants.W3C_XML_SCHEMA_NS_URI; 
    SchemaFactory factory = SchemaFactory.newInstance(language); 
    Schema schema = factory.newSchema(url); 

    validator = schema.newValidator(); 

Estrarre il SOAPBody XML e convalidare contro il Validator utilizzando il metodo validate().

eccezioni di cattura in tutto il convalida e costruire il proprio errore SOAP:

//Build the SOAP Fault Response 
MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); 
SOAPMessage response = factory.createMessage(); 

SOAPFault fault = response.getSOAPBody().addFault(); 
fault.setFaultString(myCustomErrorString); 

fault.addDetail().addChildElement("exception").addTextNode(myCustomErrorId); 

quindi restituire il SOAPMessage contenente l'errore.

(no, non mi piace Servizi Web SOAP)

+0

lol me nessuno ma a volte non siamo in grado di scegliere;) Sto cercando di mantenere lo sviluppo il più semplice possibile, quindi penso che questo possa confondere alcune persone. –

+0

Può essere utilizzato con Axis? – ctomek

2

Nello scenario che si sta cercando di ottenere, ci non sarà alcun errore SOAP. La logica di convalida (che farà parte del codice che gestisce la richiesta alla fine), deve assicurarsi che tutti gli scenari di convalida siano gestiti.

Abbiamo affrontato questo scenario in cui nella terza parte l'integrazione dei nostri servizi Web non poteva decifrare gran parte degli errori SOAP e siamo andati creando una risposta agli errori proprio come il modo in cui avete concepito. Vorrei suggerire il seguente approccio.

  • Scrivi la logica propria di convalida
  • creare una struttura oggetto appropriato. Ne hai già uno in formato XML. Ho solo bisogno di oggettivarlo.
  • Chiamare questa logica di convalida e passarvi gli oggetti di input. La logica di convalida convaliderà tutti gli input e popolerà l'oggetto di risposta appropriato (myOperationResponse).
  • Alla restituzione del metodo di convalida, verificare lo stato o gli oggetti di errore. Se ci sono errori, restituire l'oggetto risposta OPPURE procedere con l'elaborazione della richiesta ulteriormente e quindi restituire la risposta positiva.
+2

Sembra che stia già succedendo, ma il problema è che se non è possibile mappare un elemento all'oggetto jaxb, fallisce semplicemente in modo silenzioso. –

+0

Hai ragione. Solo curioso di sapere se il valore nullo dell'elemento JAXB è un indicatore sufficiente per l'errore di validazione nel tuo caso. – Santosh

+0

Non proprio. Come puoi sapere se c'è stato un errore o se è stato un elemento facoltativo che non hanno superato? –