java - test - JAX-WS-Excepciones de mapa a fallas
test jax ws web service (2)
Estoy usando JAX WS para exponer un servicio web. Algunas de las operaciones de este servicio pueden generar excepciones. No son excepciones de servidor interno, sino más bien excepciones que dependen de los argumentos de entrada de la invocación de operación.
Si especifico que mi operación arroja una Excepción personalizada, haga lo siguiente:
@WebService
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class MyServiceEndpointImpl implements MyServiceEndpoint {
@WebMethod
public void throwsException throws InvalidInputException;
}
Termino con la siguiente stacktrace cuando ejecuto la aplicación:
com.sun.xml.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class com.mypackage.ws.services.jaxws.InvalidInputExceptionBean is not found. Have you run APT to generate them?
at com.sun.xml.ws.model.RuntimeModeler.getClass(RuntimeModeler.java:285)
at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1006)
at com.sun.xml.ws.model.RuntimeModeler.processRpcMethod(RuntimeModeler.java:969)
at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:546)
at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:370)
at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:256)
at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:322)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:188)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:467)
at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:333)
at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:45)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:121)
Agregar @XmlRootEntity
a InvalidInputException
no resuelve el problema.
Si esta no es la forma recomendada de informar fallas sobre los servicios web, ¿existe una mejor manera? ¿Deberían heredar mis excepciones de RuntimeException
y confiar en el transporte para el manejo de errores (es decir, todo terminará envuelto en una excepción SOAPException)? Esperaba algo como Spring-WS '' SoapFaultAnnotationExceptionResolver
. ¿Hay algo similar disponible para JAX-WS?
¿ @WebFault
anotar su excepción con @WebFault
? Además, ¿implementa getFaultInfo()
?
EDITAR: Me doy cuenta de que mi respuesta quizás no fue lo suficientemente detallada. Como se recuerda en este hilo (por ejemplo):
La especificación JAX-WS 2.0 exige que la excepción anotada con
@WebFault
debe tener dos constructores y un método [getter para obtener la información de la falla]:
WrapperException(String message, FaultBean faultInfo) WrapperException(String message, FaultBean faultInfo, Throwable cause) FaultBean getFaultInfo()
La
WrapperException
se reemplaza por el nombre de la excepción, yFaultBean
se reemplaza por el nombre de la clase que implementa el bean de falla. El bean de falla es un bean Java que contiene la información de la falla y es utilizado por el cliente del servicio web para conocer la causa de la falla.
Esto se detalla en la sección 2.5 Fallo de la especificación JAX-WS. ¿Su excepción se ajusta a esto? ¿Puedes publicar el código?
El OP es correcto. Según la especificación 2.1, sección 3.7 Excepción específica del servicio, no es necesario usar la anotación @WebFault
, JAX-WS puede generar los beans contenedoras dinámicamente para las excepciones que no coinciden con el patrón descrito en la sección 2.5 (solo proporcione un getter para el información que desea que esté presente en la falla). Para las excepciones que coinciden con el patrón descrito en la sección 2.5 (es decir, excepciones que tienen un método getFaultInfo
y @WebFault
anotación @WebFault
), FaultBean se utiliza como entrada para JAXB al mapear la excepción al esquema XML.
Por lo tanto, la solución sugerida anteriormente (que coincide con el patrón descrito en la sección 2.5) es solo una solución. La generación de beans contenedoras debería funcionar para otras excepciones. Y no sé por qué esto falla aquí.
Una adición a la respuesta anterior. Terminé con esto como mi implementación InvalidInputException:
@WebFault(faultBean = "com.mypackage.ws.exception.FaultBean")
public class InvalidInputException extends Exception {
private static final long serialVersionUID = 1L;
private FaultBean faultBean;
public InvalidInputException() {
super();
}
public InvalidInputException(String message, FaultBean faultBean, Throwable cause) {
super(message, cause);
this.faultBean = faultBean;
}
public InvalidInputException(String message, FaultBean faultBean) {
super(message);
this.faultBean = faultBean;
}
public FaultBean getFaultInfo() {
return faultBean;
}
}
Y FaultBean
es solo un POJO simple que actualmente no tiene datos. Ahora, de acuerdo con la especificación JAX-WS (ver 3.7 Excepción específica del servicio), se ajusta a lo que se requiere de una excepción anotada con @WebFault, por lo que no creará un bean envoltorio para ella, que probablemente sea lo que falló.
Esta es una solución decente, pero no explica el error en la pregunta.