2010-02-03 8 views
14

Pracuję nad usługą internetową Apache CXF (przy użyciu JAX-WS, przez SOAP). Sama usługa jest dość prosta: odbierz żądanie, wstaw zapytanie do bazy danych i zwróć informację, czy wstawienie zakończyło się pomyślnie. Chciałbym polegać na sprawdzaniu poprawności XML w celu wymuszenia kilku ograniczeń na żądanie.Sprawdzanie poprawności XML po stronie serwera za pomocą CXF Webservice

Moje pytanie. Jak zwrócić szczegółowe błędy sprawdzania poprawności do klienta mojej usługi? Sprawdziłem poprawność serwera po stronie serwera, konfigurując mój punkt końcowy.

<jaxws:endpoint id="someEndpoint" implementor="#someImpl" address="/impl"> 
    <jaxws:properties> 
     <!-- This entry should- ideally- enable JAXB validation 
     on the server-side of our web service. --> 
     <entry key="schema-validation-enabled" value="true" /> 
    </jaxws:properties> 
</jaxws:endpoint> 

mam zbadane za pomocą przechwytujących (np BareInInterceptor) na serwerze, a jakoś wzrok SAXParseExceptions je owinąć i wysłać je wraz z klientem. Takie podejście wydaje się nieco skomplikowane, ale muszę podać klientom numer linii, jeśli ich XML jest nieprawidłowy. Czy powinienem iść z przechwytującymi, aby ujawnić wyjątki?

Nie mam dużego doświadczenia z tą technologią i po prostu wchodzę do serwisów internetowych - wszelkie wskazówki, które możecie mi dać, będą naprawdę mile widziane.

+2

Należy pamiętać, że jeśli XML w zapytaniu jest generowany przez aplikację kliencką SOAP (jak można dostać od generowania odcinki z własnego Service), numer linii jest prawdopodobnie 1 bardzo często (ponieważ wiele klienci po prostu wygenerują dokument XML o bardzo długiej linii). –

+0

@Ian McLaird: to jest ważne uwagi, z drugiej strony, gdy aplikacja jest testowana przez testerów, używają lepsze formatowanie i będzie to ich – Betlista

Odpowiedz

26

Można zastąpić komunikaty o błędach walidacji, wstawiając numer linii, za pomocą niestandardowego ValidationEventHandler:

package example; 

import javax.xml.bind.ValidationEvent; 
import javax.xml.bind.helpers.DefaultValidationEventHandler; 

public class MyValidationEventHandler extends DefaultValidationEventHandler {  
    @Override 
    public boolean handleEvent(ValidationEvent event) { 
     if (event.getSeverity() == ValidationEvent.WARNING) { 
      return super.handleEvent(event); 
     } else { 
      throw new RuntimeException(event.getMessage() 
       + " [line:"+event.getLocator().getLineNumber()+"]"); 
     } 
    } 
} 

przypadku konfigurowania punktu końcowego do korzystania z tego Handler:

<jaxws:endpoint id="someEndpoint" implementor="#someImpl" address="/impl"> 
    <jaxws:properties> 
     <entry key="schema-validation-enabled" value="true" /> 
     <entry key="jaxb-validation-event-handler"> 
      <bean class="example.MyValidationEventHandler" /> 
     </entry> 
    </jaxws:properties> 
</jaxws:endpoint> 

Wtedy dostaniesz Błędy SOAP, które wyglądają tak:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
     <soap:Fault> 
      <faultcode>soap:Client</faultcode> 
      <faultstring>Unmarshalling Error: Not a number: xyz [line: 6]</faultstring> 
     </soap:Fault> 
    </soap:Body> 
</soap:Envelope> 

The jaxb-validation-ev Właściwość ent-handler została dodana do CXF dopiero niedawno, więc musisz upewnić się, że używasz najnowszej wersji - testowałem to z 2.2.5.

+0

pomoc dam tego spróbować w godzinach porannych! –

+0

To działa świetnie, morze - nagroda jest twoja. –

+0

Wygląda na to, że to podejście nie działa poprawnie dla CXF 2.2.9. To będzie nadal zwracać numer wiersza dla przypadku, gdy podano niepoprawną wartość daty, ale numer wiersza będzie niepoprawny. W przypadku innych wyjątków f.e. zerwane ograniczenie długości łańcucha nie spowoduje dołączenia numeru linii, a initil SAXParseException zostanie zwrócony. Tak więc, jak rozumiem, jest jeden sposób - obsługa błędów i ponownej analizy składniowej dokumentu, gdy otrzymał SAXParseExceptions. – Milkywayfarer