J'utilise JAX WS pour exposer un WebService. Certaines opérations de ce service peuvent générer des exceptions. Pas d'exceptions de serveur internes, mais plutôt des exceptions qui dépendent des arguments d'entrée de l'appel d'opération.
Si je spécifie que mon opération lève une exception personnalisée, comme ceci:
@WebService
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class MyServiceEndpointImpl implements MyServiceEndpoint {
@WebMethod
public void throwsException throws InvalidInputException;
}
Je me retrouve avec la trace de pile suivante lors de l'exécution de l'application:
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)
Ajouter @XmlRootEntity
à InvalidInputException
ne résout pas le problème.
Si ce n'est pas la façon recommandée de signaler les erreurs sur les services Web, existe-t-il une meilleure façon? Mes exceptions devraient-elles hériter de RuntimeException
et s'appuyer sur le transport pour la gestion des erreurs (c'est-à-dire que tout finira enveloppé dans une SOAPException)? J'espérais quelque chose comme Spring-WS 'SoapFaultAnnotationExceptionResolver
. Existe-t-il quelque chose de similaire pour JAX-WS?
Avez-vous essayé d'annoter votre exception avec @WebFault
? De plus, implémentez-vous getFaultInfo()
?
EDIT: Je réalise que ma réponse n'était peut-être pas assez détaillée. Comme rappelé dans ce fil (par exemple):
La spécification JAX-WS 2.0 exige que l'exception annotée avec
@WebFault
Doit avoir deux constructeurs et une méthode [getter pour obtenir les informations de panne]:WrapperException(String message, FaultBean faultInfo) WrapperException(String message, FaultBean faultInfo, Throwable cause) FaultBean getFaultInfo()
WrapperException
est remplacé par le nom de l'exception etFaultBean
est remplacé par le nom de classe qui implémente le bean d'erreur. Le bean d'erreur est un bean Java qui contient les informations de l'erreur et est utilisé par le client du service Web pour connaître la cause de l'erreur.
Ceci est détaillé dans la section 2.5 Erreur de la spécification JAX-WS. Votre exception est-elle conforme à cela? Pouvez-vous poster le code?
L'OP a raison. Conformément à la spécification 2.1, section 3.7 Exception spécifique au service, il n'est pas nécessaire d'utiliser l'annotation @WebFault
, JAX-WS peut générer dynamiquement les beans wrapper pour les exceptions qui ne correspondent pas au modèle décrit dans la section 2.5 (fournissez simplement un getter pour les informations que vous souhaitez être présent dans le défaut). Pour les exceptions qui correspondent au modèle décrit dans la section 2.5 (c'est-à-dire les exceptions qui ont une méthode getFaultInfo
et une annotation @WebFault
), FaultBean est utilisé comme entrée dans JAXB lors du mappage de l'exception au schéma XML.
La solution suggérée ci-dessus (correspondant au modèle décrit dans la section 2.5) n'est donc qu'une solution de contournement. La génération de beans wrapper ne devrait fonctionner que pour d'autres exceptions. Et je ne sais pas pourquoi cela échoue ici.
Un ajout à la réponse ci-dessus. Je me suis retrouvé avec cela comme implémentation 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;
}
}
Et FaultBean
n'est qu'un simple POJO avec actuellement aucune donnée du tout. Maintenant, selon la spécification JAX-WS (voir 3.7 Exception spécifique au service), il est conforme à ce qui est requis d'une exception annotée avec @WebFault, donc il ne créera pas de bean wrapper pour lui, ce qui est probablement ce qui échouait.
Il s'agit d'une solution de contournement décente, mais cela n'explique pas l'erreur dans la question.