2010-01-07 17 views
21

Dans Jersey, comment pouvons-nous «remplacer» la chaîne d'état associée à un code d'état connu?JAX/Jersey Code d'erreur personnalisé en réponse

par exemple.

return Response.status(401).build(); 

génère une réponse HTTP qui contient:

HTTP/1.1 401 Unauthorized 

I (pas moi, mais l'application cliente) souhaite voir la réponse que:

HTTP/1.1 401 Authorization Required 

J'ai essayé les suivantes approches mais en vain:

1) Cela ajoute juste la chaîne dans le corps de la réponse HTTP

return Response.status(401).entity("Authorization Required").build(); 

2) Même résultat avec cela aussi:

ResponseBuilder rb = Response.status(401); 
rb = rb.tag("Authorization Required"); 
return rb.build(); 

apprécie votre aide!

-SPd

Répondre

36

Pour ce faire, à Jersey, vous avez le concept de classe WebApplicationException. Une méthode consiste simplement à étendre cette classe et toutes les méthodes pour définir le texte d'erreur renvoyé. Dans votre cas, ce serait:

import javax.ws.rs.*; 
import javax.ws.rs.core.*; 
import javax.ws.rs.core.Response.*; 


public class UnauthorizedException extends WebApplicationException { 

    /** 
     * Create a HTTP 401 (Unauthorized) exception. 
    */ 
    public UnauthorizedException() { 
     super(Response.status(Status.UNAUTHORIZED).build()); 
    } 

    /** 
     * Create a HTTP 404 (Not Found) exception. 
     * @param message the String that is the entity of the 404 response. 
     */ 
    public UnauthorizedException(String message) { 
     super(Response.status(Status.UNAUTHORIZED).entity(message).type("text/plain").build()); 
    } 

} 

maintenant dans votre code qui implémente le service de repos vous simplement lancer une nouvelle exception de ce type, en passant de la valeur de texte dans le constructeur par exemple

throw new UnauthorizedException("Authorization Required"); 

Cela peut créer une classe comme celle-ci pour chacune de vos exceptions Web et lancer de la même manière.

Ceci est expliqué également dans le guide de l'utilisateur Jersey - bien que le code est en fait un peu incorrect:

https://jersey.github.io/nonav/documentation/latest/user-guide.html/#d4e435

+1

L'OP n'a-t-il pas demandé le chemin autre que «entity (message)»? –

+1

D'accord avec @JinKwon, en quoi est-ce différent de 1) dans la question de OP? – TWiStErRob

4

Je ne suis pas sûr JSR 339: JAX-RS 2.0: The Java API for RESTful Web Services déjà couvert ou non.

Vous devrez peut-être étendre le Response.StatusType pour cela.

public abstract class AbstractStatusType implements StatusType { 

    public AbstractStatusType(final Family family, final int statusCode, 
           final String reasonPhrase) { 
     super(); 

     this.family = family; 
     this.statusCode = statusCode; 
     this.reasonPhrase = reasonPhrase; 
    } 

    protected AbstractStatusType(final Status status, 
           final String reasonPhrase) { 
     this(status.getFamily(), status.getStatusCode(), reasonPhrase); 
    } 

    @Override 
    public Family getFamily() { return family; } 

    @Override 
    public String getReasonPhrase() { return reasonPhrase; } 

    @Override 
    public int getStatusCode() { return statusCode; } 

    public ResponseBuilder responseBuilder() { return Response.status(this); } 

    public Response build() { return responseBuilder().build(); } 

    public WebApplicationException except() { 
     return new WebApplicationException(build()); 
    } 

    private final Family family; 
    private final int statusCode; 
    private final String reasonPhrase; 
} 

Et voici quelques types d'états étendus.

public class BadRequest400 extends AbstractStatusType { 

    public BadRequest400(final String reasonPhrase) { 
     super(Status.BAD_REQUEST, reasonPhrase); 
    } 
} 

public class NotFound404 extends AbstractStatusType { 

    public NotFound404(final String reasonPhrase) { 
     super(Status.NOT_FOUND, reasonPhrase); 
    } 
} 

Voici comment je le fais.

@POST 
public Response create(final MyEntity entity) { 

    throw new BadRequest400("bad ass").except(); 
} 

@GET 
public MyEntity read(@QueryParam("id") final long id) { 

    throw new NotFound404("ass ignorant").except(); 
} 

// Disclaimer 
// I'm not a native English speaker. 
// I don't know what 'bad ass' or 'ass ignorant' means. 
+1

Eh bien, merci de m'avoir fait voir que Status a une interface avec laquelle je peux jouer! – TWiStErRob

+0

Cette approche ne semble pas fonctionner avec Jersey car elle a une classe "com.sun.jersey.core.spi.factory.ResponseImpl" qui a sa propre logique pour obtenir le StatusType. –