2013-01-21 3 views
0

Je développe une application client-serveur avec JAX-RS/Apache CXF, JSONMapping d'exception personnalisée dans JAX-RS par annotation @WebFault

Je voudrais Apache CXF à gérer mon exception de manière transparente aux deux extrémités: ce qui signifie transformer l'exception en un bean, en la sérialisant avec mon Jackson Serializer (JSON), puis en faisant le tour du côté client.

J'ai vu plusieurs messages confus/réponses à ce sujet et est venu avec l'aide de l'annotation @WebFault:

@WebFault(name=CODE, faultBean="foo.bar.FaultBean") 
public class DuplicateRuleNameFault extends Exception { 
    static final public String CODE = "DUPLICATE_RULE_NAME"; 
    private FaultBean faultBean; 

    public DuplicateRuleNameFault(String msg) { 
    super(msg); 
    this.faultBean = new FaultBean(msg); 
    } 
    public DuplicateRuleNameFault() { 
    } 
    public FaultBean getFaultBean() { 
    return faultBean; 
    } 
    public void setFaultBean(FaultBean faultBean) { 
    this.faultBean = faultBean; 
    } 
} 

sans succès ... À l'heure actuelle, CXF semble ignorer joyeusement l'annotation sur l'exception et le gérer comme une exception inconnue: erreur d'état 500 et aucun corps de réponse généré côté serveur.

Y a-t-il quelque chose de spécifique que je dois configurer dans l'élément "" serveur de mon contexte Spring? J'ai déjà Spring en train de scanner mes classes Exception/FaultBean (est-ce que c'est même nécessaire BTW?).

J'apprécierais que vous me donniez un exemple de travail. Merci.

+0

pouvez-vous s'il vous plaît partager comment vous avez fait la solution ... je suis face à la même question :( – vashishth

+0

Nous avons passé à « exception fonctionnelle »: Nous avons un mappeur d'exception sur le côté cserver qui construit JSON de coutume sur une exception. Ensuite, du côté client, j'utilise un inInterceptor pour JRS unmarshal et lancer une exception en réponse à une erreur. –

Répondre

3

@WebFault's ne font pas partie de la spécification JAX-RS. Vous voudrez lire sur section 3.3.4 de la spécification, qui décrit les différentes façons dont vous pouvez accomplir ce que vous essayez de faire.

Option 1

Concevez vos classes de ressources pour jeter WebApplicationException's. Définissez la propriété response de ces exceptions comme étant une réponse JAX-RS valide contenant les beans de faute que vous souhaitez envoyer au client.

Option 2

Définir les fournisseurs de cartographie d'exception. Vous pouvez en créer une hiérarchie pour gérer toutes les exceptions courantes que votre application lancera. Vous pouvez également créer une exception de niveau supérieur avec un bean intégré et un gestionnaire d'exceptions. Et puis dérivez plusieurs exceptions spécifiques du premier niveau.

public abstract class MyApplicationException<T> extends Exception { 
    private T faultBean; 

    // Constructors, setters/getters 
} 

@Provider 
public class MyApplicationExceptionHandler implements ExceptionMapper<MyApplicationException<?>> { 
    // Implementation 
} 
+0

Merci. Je l'ai fait comme ça, avec un ExceptionMaopper sur SS et un ResponseExceptionMapper sur le client. –

0

Une façon de le faire est en utilisant l'objet javax.ws.rs.core.Response comme ceci:

@GET

@Path ("/")

Réponse publique getBlah()

{

try { 
    return Response.status(Response.Status.OK) 
      .entity(<Object you want to return>).build(); 
} 
catch (final DuplicateRuleNameFault e) { 
    return Response.status(Response.Status.BAD_REQUEST) 
      .entity(e.getFaultBean().getMsg()).build(); 
} 

}

+0

Bien sûr, mais de cette façon, je devrai aussi gérer l'analyse de l'Exception à la main du côté client. Je voudrais prendre l'avantage de JAX-RS et CXF qui permet d'instancier dynamiquement le client en entourant une définition de service, au sein d'une seule ligne de code. –

Questions connexes