Validación XML del lado del servidor con CXF WebService
-
25-09-2019 - |
Pregunta
Estoy trabajando en un servicio web de Apache CXF (usando Jax-WS, sobre SOAP). El servicio en sí es bastante simple: reciba una solicitud, inserte la solicitud en una base de datos y devuelva si el inserto fue exitoso. Me gustaría confiar en la validación de XML para hacer cumplir una serie de restricciones en la solicitud.
Entonces, mi pregunta. ¿Cómo devuelvo los errores de validación detallados a un cliente de mi servicio? He cambiado la validación en el lado del servidor configurando mi punto final.
<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>
He explorado el uso de interceptores (por ejemplo, BareIninterceptor) en el servidor, y de alguna manera capturando SaxParseExcepciones para envolverlos y enviarlos al cliente. Este enfoque parece un poco complicado, pero de alguna manera necesito dar a los clientes un número de línea si su XML no es válido. ¿Debo ir con interceptores para exponer las excepciones?
No tengo mucha experiencia con esta pila de tecnología, y solo ingreso a los servicios web, cualquier consejo que puedan darme sería realmente apreciado.
Solución
Puede anular los mensajes de error de validación, insertando un número de línea, utilizando una validación personalizada, ENCUENTRO:
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()+"]");
}
}
}
Si configura su punto final para usar este controlador:
<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>
Entonces recibirás fallas de jabón que se ven así:
<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>
La propiedad JAXB-Validation-Event-Handler solo se agregó a CXF muy recientemente, por lo que debe asegurarse de que está utilizando la última versión: probé esto con 2.2.5.