web-dev-qa-db-fra.com

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

J'ai un REST Service intégré à l'aide de Jersey.

Je veux pouvoir définir le mime de mes écrivains d'exception personnalisés en fonction du mime envoyé au serveur. application/json est retourné lorsque JSON est reçu et application/xml Lorsque XML est reçu.

Maintenant I Code difficile application/json, mais cela rend les clients XML laissés dans le noir.

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 exploiter pour obtenir les demandes actuelles Content-Type?

Merci!


Mise à jour basée sur la réponse

Pour quelqu'un d'autre intéressé 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é

45
Oskar

Vous pouvez essayer d'ajouter un @ javax.ws.rs.core.context javax.ws.rs.core.httptheaders champ/propriété sur votre classe de ressources root, paramètre de méthode de ressource ou à une javax.ws.r.ext personnalisé.ExceptionMapper et appeler httpheaders.getmediatype ().

26
Bryant Luk

headers.getmediatype () répond avec le type de support de l'entité et non l'en-tête accepté. Le moyen approprié de convertir l'exception est que l'en-tête accepte de sorte que votre client obtient la réponse au format qu'ils ont demandé. Compte tenu de la solution ci-dessus, si votre demande ressemble à ce qui suit (note JSON accepte l'en-tête, mais une entité XML), vous obtiendrez une liste XML.

[.____] Poster http: // localhost: 8080/Service/GiftCard/Facture? Projet = true http/1.1 [.____] Accepter: Application/Json [ Type de contenu: Application/XML [.____] User-Agent: Jakarta Commons-httpClient/3.1 [.____] Host: localHost: 8080 [.____ -Lengthre: 502 [

La bonne implémentation est à nouveau pour 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();
}
15
Domenic D.