web-dev-qa-db-fra.com

Comment valider au mieux les entrées JAX-WS?

J'écris actuellement un nouvel ensemble de services Web utilisant JAX-WS, mais je ne parviens pas à choisir le meilleur moyen de valider les entrées. Je peux effectuer quelques validations dans mes classes d'implémentation mais certaines erreurs d'entrée échouent en silence. Par exemple, les données de caractère dans un élément numérique génèrent un entier NULL dans l'objet JAXB.

Ce sont les dessins que j'ai rencontrés.

  1. @SchemaValidation
    Je pourrais ajouter cette annotation à la classe de points de terminaison et JAX-WS se chargera de la validation. Cela a fonctionné localement dans Tomcat, mais il est à craindre que cela ne fonctionne pas sur certains serveurs. Mon principal reproche est que je dois abandonner le contrôle de la manière dont les erreurs sont générées dans la réponse.

  2. Toutes les entrées en tant que chaînes
    Je déteste cette approche, mais j’ai vu d’autres services Web où toutes les entrées sont définies en tant que chaînes. Cela attraperait le cas de données de caractères dans un élément numérique car je pourrais le vérifier à l’appel de notre API, même si vous manqueriez encore des éléments xml mal nommés.

Je veux vraiment que les erreurs reviennent de la même manière que les erreurs d'API plutôt que comme une faute de savon. Des idées? J'ai vu quelques sites parler d'intercepter la demande avec une sorte de filtre. Vous ne savez pas comment cela fonctionnerait avec différentes réponses pour différentes opérations.

PAR EXEMPLE.

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

Peut-être que je demande trop, mais je pensais voir si j'avais oublié quelque chose. TIA.

11
Ben Thurley

Trouvé cet article qui explique une voie possible.
http://one-size-doesnt-fit-all.blogspot.co.uk/2009/04/jax-ws-schemavalidation-custom-handler.html

Je l'ai renvoyé le message d'erreur d'analyse dans ma mise en page de réponse standard. je dois juste tester que cela fonctionnera sur la machine du client. (Certaines personnes disent qu'elles ont eu des problèmes avec @SchemaValidation)

7
Ben Thurley

Si vous insistez sur le contrôle (vous devez généralement renoncer à Jax-WS, par exemple), vous pouvez implémenter un fournisseur et un validateur validant sur un schéma XSD.

Le schéma XSD se chargera de valider l'entrée (type et potentiellement énumérations, correspondance de modèle, etc ...)

Pour implémenter le javax.xml.ws.Provider en tant que votre noeud final SOAP, créez une classe ressemblant à

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

Une SOAPMessage sera transmise à la méthode invoke qui attend en retour une réponse valide ou SOAPFault encapsulée dans un message SOAPMessage;

Pour valider un XSD, utilisez 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();

Extrayez SOAPBody xml et validez-le par rapport à Validator en utilisant la méthode validate().

Catch Exceptions autour de la validation et construire votre propre SOAP Fault:

 //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);

puis renvoyez le message SOAP contenant le défaut.

(non, je n'aime pas les services Web SOAP)

7
Bruno Grieder

Dans le scénario que vous essayez d’atteindre, il y a il n’y aura pas de SOAP fautif. La logique de validation ( qui fera partie du code qui gérera éventuellement la demande ), doit assurez-vous que tous les scénarios de validation sont gérés. 

Nous avions été confrontés à des scénarios dans lesquels, en intégrant nos services Web à la tierce partie, nous ne pouvions pas beaucoup déchiffrer les fautes SOAP et nous nous sommes alors engagés en créant une réponse-erreur à l’image de votre conception. Je suggérerais l'approche suivante. 

  • Écrivez votre propre logique de validation
  • Créez une structure d'objet appropriée. Vous en avez déjà un au format XML. Juste besoin de l'objectiver.
  • Appelez cette logique de validation et transmettez-lui les objets d'entrée. La logique de validation va valider toutes les entrées et renseigner l'objet de réponse approprié (myOperationResponse). 
  • Au retour de la méthode de validation, recherchez les objets status ou error. S'il y a des erreurs, retournez l'objet de réponse OR, poursuivez le traitement de la demande, puis renvoyez la réponse. 
2
Santosh

Je ne sais pas si je vous comprends bien, mais cela vous aide: 

http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html

0
Dennis Kriechel