44 votes

Exception personnalisée JAX-RS (Jersey) avec XML ou JSON

J'ai un service REST construit en utilisant Jersey.

Je veux pouvoir définir le MIME de mes rédacteurs d'exceptions personnalisés en fonction du MIME qui a été envoyé au serveur. application/json est retourné lorsque json est reçu, et application/xml lorsque le xml est reçu.

Maintenant, je code dur application/json mais c'est laisser les clients XML dans l'ignorance.

public class MyCustomException extends WebApplicationException {
     public MyCustomException(Status status, String message, String reason, int errorCode) {
         super(Response.status(status).
           entity(new ErrorResponseConverter(message, reason, errorCode)).
           type("application/json").build());
     }
}

Quel contexte puis-je utiliser pour obtenir les demandes actuelles ? Content-Type ?

Gracias.


Mise à jour en fonction de la réponse

Pour toute autre personne intéressée par la solution complète :

public class MyCustomException extends RuntimeException {

    private String reason;
    private Status status;
    private int errorCode;

    public MyCustomException(String message, String reason, Status status, int errorCode) {
        super(message);
        this.reason = reason;
        this.status = status;
        this.errorCode = errorCode;
    }

    //Getters and setters
}

Avec un ExceptionMapper

@Provider
public class MyCustomExceptionMapper implements ExceptionMapper<MyCustomException> {

    @Context
    private HttpHeaders headers;

    public Response toResponse(MyCustomException e) {
        return Response.status(e.getStatus()).
                entity(new ErrorResponseConverter(e.getMessage(), e.getReason(), e.getErrorCode())).
                type(headers.getMediaType()).
                build();
    }
}

Où ErrorResponseConverter est un POJO JAXB personnalisé.

25voto

Bryant Luk Points 1186

Vous pouvez essayer d'ajouter un champ/propriété @javax.ws.rs.core.Context javax.ws.rs.core.HttpHeaders à votre classe de ressource racine, au paramètre de méthode de la ressource ou à un javax.ws.rs.ext.ExceptionMapper personnalisé et appeler HttpHeaders.getMediaType().

15voto

Domenic D. Points 1265

Headers.getMediaType() répond avec le type de média de l'entité, et non l'en-tête Accept. La façon appropriée de convertir l'exception est avec l'en-tête Accept afin que votre client obtienne la réponse dans le format qu'il a demandé. Compte tenu de la solution ci-dessus, si votre requête ressemble à ce qui suit (notez l'en-tête Accept JSON, mais l'entité XML), vous obtiendrez une réponse XML.

POST http://localhost:8080/service/giftcard/invoice?draft=true HTTP/1.1
Accept: application/json
Authorization: Basic dXNlcjp1c2Vy
Content-Type: application/xml
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8080
Proxy-Connection: Keep-Alive
Content-Length: 502
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><sample><node1></node1></sample>

L'implémentation correcte consiste à nouveau à utiliser l'en-tête Accept :

public Response toResponse(final CustomException e) {
    LOGGER.debug("Mapping CustomException with status + \"" + e.getStatus() + "\" and message: \"" + e.getMessage()
            + "\"");
    ResponseBuilder rb = Response.status(e.getStatus()).entity(
            new ErrorResponseConverter(e.getMessage(), e.getReason(), e.getErrorCode()));

    List<MediaType> accepts = headers.getAcceptableMediaTypes();
    if (accepts!=null && accepts.size() > 0) {
        //just pick the first one
        MediaType m = accepts.get(0);
        LOGGER.debug("Setting response type to " + m);
        rb = rb.type(m);
    }
    else {
        //if not specified, use the entity type
        rb = rb.type(headers.getMediaType()); // set the response type to the entity type.
    }
    return rb.build();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X