2010-01-14 14 views
26

Estoy utilizando 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.JAX-WS - Mapa Excepciones a las fallas

Si especifico que mi operación arroja una excepción personalizada, así:

@WebService 
@SOAPBinding(style = Style.RPC, use = Use.LITERAL) 
public class MyServiceEndpointImpl implements MyServiceEndpoint { 

    @WebMethod 
    public void throwsException throws InvalidInputException; 
} 

termino con la siguiente StackTrace al ejecutar 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) 

Adición @XmlRootEntity-InvalidInputException no lo hace resolver el problema.

Si esta no es la forma recomendada de informar fallas sobre los servicios web, ¿hay alguna otra manera mejor? ¿Mis excepciones deben heredar 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?

+0

Quizás debería tener en cuenta que la clase informa como faltante, com.mypackage.ws.services.jaxws.InvalidInputExceptionBean, de hecho no existe. Pero asumí que era natural, que debería generarse como los estados de excepción. – waxwing

Respuesta

25

¿Intentó anotar su excepción con @WebFault? Además, ¿implementa getFaultInfo()?

EDIT: Me doy cuenta de que mi respuesta quizás no fue lo suficientemente detallada. Como recordado en this thread (por ejemplo):

La especificación JAX-WS 2.0 exige que la excepción anotado con @WebFault debe tener dos constructores y un método [getter para obtener la información de defecto]:

WrapperException(String message, FaultBean faultInfo) 
WrapperException(String message, FaultBean faultInfo, Throwable cause) 
FaultBean getFaultInfo() 

el WrapperException se sustituye por el nombre de la excepción, y FaultBean se sustituye por el nombre de la clase que implementa el frijol culpa. El bean de error es un bean Java que contiene la información del error y lo utiliza 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 utilizar 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 (simplemente proporcione un getter para la información quieres estar 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 una anotación @WebFault), FaultBean se utiliza como entrada a JAXB al mapear la excepción al esquema XML.

Por lo que la solución sugerida anteriormente (que coincide con el patrón descrito en la sección 2.5) es solo una solución alternativa. La generación de beans contenedoras debería funcionar para otras excepciones. Y no sé por qué esto falla aquí.

+0

No lo hice. Intenté eso ahora, pero obtengo el mismo error. Pero, ¿debo especificar el nombre de las propiedades de @ WebFault, targetNameSpace y faultBean también? – waxwing

+0

Gracias por la pista, lo investigaré. No, no implementé los constructores que indicó. Leí (¿leí mal?) Esa parte de la especificación, ya que la implementación de JAX WS generaría * automáticamente el propio envoltorio de excepción con esos constructores. Estoy empezando a pensar que estoy haciendo algo al revés ... – waxwing

+0

Resulta que ajustarse al estilo de Excepción que escribió anteriormente significa que JAX-WS * no * creará un bean envoltorio para la excepción, que de lo contrario debería. Entonces eso funciona como una solución para mí. Sin embargo, * debería * funcionar con todas las excepciones sin anotaciones, de acuerdo con "3.7 Excepción específica del servicio" en la especificación. – waxwing

16

Además de la respuesta anterior. Terminé con esto como mi aplicació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 sólo un POJO simple, con actualmente no hay datos en absoluto. 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.

+1

+1 por esto, me salvó el día :). Pero esto solo funciona para las excepciones comprobadas, no para las excepciones no marcadas. Alguna pista ... – mogli

+0

@waxwing He implementado un ejemplo; sin embargo, mi ejemplo no funciona sin definir el elemento targetNamespace? – kamaci

+0

@rits Bueno, me pasó lo mismo Probé esto en Websphere 8.5.5, que tiene Axis 2 como proveedor de servicios para JAX-WS y no funcionaba con RuntimeException, pero funcionaba igual que con Websphere Liberty Profile porque usa Apache CXF en su lugar. Es una pena en realidad porque ahora mi cliente necesita atrapar/declarar la excepción. –

Cuestiones relacionadas