2013-07-04 7 views
11

Obecnie piszę nowy zestaw usług internetowych przy użyciu JAX-WS, ale mam trudności z podjęciem decyzji o najlepszym sposobie sprawdzania poprawności danych wejściowych. Mogę wykonać pewne sprawdzanie poprawności w moich klasach implementacji, ale niektóre błędy wejściowe nie działają po cichu. Na przykład dane znakowe w elemencie numerycznym będą skutkowały pustą liczbą całkowitą w obiekcie JAXB.Jak najlepiej sprawdzić wejścia JAX-WS?

Oto projekty, które spotkałem.

  1. @SchemaValidation
    mogę dodać adnotację do klasy końcowego i JAX-WS zajmie walidacji. To działało lokalnie w tomcat, ale istnieją obawy, że nie zadziała na niektórych serwerach. Moim głównym zarzutem jest to, że muszę poddać kontroli, w jaki sposób błędy są wyprowadzane w odpowiedzi.

  2. Wszystkie dane wejściowe jako ciągi znaków
    Nienawidzę tego podejścia, ale widziałem inne usługi internetowe, w których wszystkie dane wejściowe są zdefiniowane jako ciągi. To mogłoby uchwycić przypadek danych znakowych w elemencie numerycznym, ponieważ mogłem to sprawdzić, gdybym zadzwonił do naszego API, chociaż nadal brakowałoby ci nieprawidłowo nazwanych elementów xml.

Naprawdę chcę, aby błędy powracały w taki sam sposób, jak błędy API, a nie jako błąd mydła. Jakieś pomysły? Widziałem kilka witryn mówiących o przechwytywaniu żądania za pomocą pewnego rodzaju filtru. Nie wiem jednak, jak to by działało w przypadku różnych odpowiedzi dla różnych operacji.

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> 

Może za dużo żądam, ale pomyślałem, że zobaczę, czy coś przeoczyłem. TIA.

Odpowiedz

7

Ten artykuł objaśnia jeden z możliwych sposobów.
http://one-size-doesnt-fit-all.blogspot.co.uk/2009/04/jax-ws-schemavalidation-custom-handler.html

Mam to zwrócenie komunikatu o błędzie analizowania w moim standardowym układzie odpowiedzi. Muszę tylko przetestować, że będzie działać na komputerze klienta. (Niektórzy ludzie mówią, że mieli problemy z @SchemaValidation)

+0

Upomnienie właśnie mi o tym przypomniało. To jest teraz w produkcji dla kilku projektów i nie mieliśmy żadnych problemów. –

7

Jeśli nalegać na kontrolę (coś jak zwykle trzeba zrezygnować, gdy robi JAX-WS ...) , możesz zaimplementować dostawcę i walidatora walidującego ze schematem XSD.

XSD Schema zajmie walidacji wejścia (typ i potencjalnie wyliczeń, pasujące do wzorca, etc ...)

do wdrożenia javax.xml.ws.Provider jako mydło końcowy, należy utworzyć klasę patrząc jak

@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 zostanie przekazana do metody invoke, która oczekuje w zamian prawidłowej odpowiedzi lub komunikatu SOAPFault zawiniętego w komunikat SOAP;

Aby potwierdzić agains XSD, użyć 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(); 

Ekstrahować SOAPBody xml, zatwierdź przed Validator stosując metodę validate().

połowowe wyjątkami całym walidacji i budowania własnej winy 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); 

następnie zawróci SOAPMessage zawierającego usterkę.

(nie, nie lubię SOAP Web Services)

+0

lol mnie ani, ale czasami nie mamy wyboru;) Staram się, aby rozwój był tak prosty, jak to tylko możliwe, więc myślę, że może to zmylić niektórych ludzi. –

+0

Czy można go używać z Axis? – ctomek

2

w scenariuszu, który próbujesz osiągnąć, nie przyzwyczajenie się jakichkolwiek błędów SOAP. Logika walidacji (, która będzie częścią kodu, który obsługuje żądanie ostatecznie), musi upewnić się, że wszystkie scenariusze walidacji są obsługiwane.

Mieliśmy do czynienia z tymi scenariuszami, w których strona trzecia integrująca nasze usługi internetowe nie mogła odszyfrować wiele od błędów SOAP i udaliśmy się tworząc reakcję na błąd tak, jak to sobie wymyśliliście. Sugerowałbym następujące podejście.

  • Napisz własną logikę walidacji
  • stworzyć odpowiednią strukturę obiektu. Masz już jeden w formacie XML. Wystarczy zobiektywizować to.
  • Wywołaj tę logikę walidacji i przekaż do niej obiekty wejściowe. Logika walidacji sprawdzi wszystkie wejścia i wypełni odpowiedni obiekt odpowiedzi (myOperationResponse).
  • Po zwrocie metody sprawdzania poprawności sprawdź obiekty stanu lub błędu. Jeśli wystąpią błędy, zwróć obiekt odpowiedzi LUB kontynuuj przetwarzanie żądania dalej, a następnie zwróć odpowiedź o powodzeniu.
+2

To brzmi jak to, co już się dzieje, ale problem polega na tym, że nie można odwzorować elementu na obiekt jaxb, a następnie po prostu nie powiedzie się po cichu. –

+0

Masz rację. Po prostu ciekawy, czy wartość pusta elementu JAXB jest wystarczającym wskaźnikiem niepowodzenia sprawdzania poprawności w twoim przypadku. – Santosh

+0

Niezupełnie. Jak rozpoznać, czy wystąpił błąd lub czy był to element opcjonalny, którego nie przepuszczono? –