2010-01-07 20 views
21

En Jersey, ¿cómo podemos 'reemplazar' la cadena de estado asociada con un código de estado conocido?JAX/Jersey Código de error personalizado en la respuesta

p. Ej.

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

genera una respuesta HTTP que contiene:

HTTP/1.1 401 Unauthorized 

I (no yo, sino la aplicación cliente) le gustaría ver la respuesta como:

HTTP/1.1 401 Authorization Required 

He intentado lo siguiente se acerca, pero en vano:

1) Esto simplemente agrega la cadena en el cuerpo de la respuesta HTTP

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

2) El mismo resultado con esto también:

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

apreciamos su ayuda!

-spd

Respuesta

36

Para ello en Jersey que tiene el concepto de clase WebApplicationException. Un método es simplemente extender esta clase y todos los métodos para establecer el texto de error que se devuelve. En su caso esto sería:

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()); 
    } 

} 

Ahora en su código que implementa el resto servicio sólo tendría que lanzar una nueva excepción de este tipo, que pasa en el valor de texto en el constructor, por ejemplo,

throw new UnauthorizedException("Authorization Required"); 

Eso puede crear una clase como esta para cada una de sus excepciones web y lanzar de una manera similar.

Esto también se explica en la guía de usuario Jersey - aunque el código es en realidad un poco incorrecto:

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

+1

¿El OP no preguntó otra cosa que 'entidad (mensaje)'? –

+1

De acuerdo con @JinKwon, ¿cómo es esto diferente de 1) en la pregunta de OP? – TWiStErRob

4

No estoy seguro de JSR 339: JAX-RS 2.0: The Java API for RESTful Web Services ya cubierto o no.

Puede que tenga que extender el Response.StatusType para esto.

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; 
} 

Y aquí hay algunos tipos de estados ampliados.

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); 
    } 
} 

Así es como lo hago.

@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

Bien, gracias por hacerme ver que Status tiene una interfaz con la que puedo meterme. – TWiStErRob

+0

Este enfoque no parece funcionar con Jersey, ya que tiene una clase "com.sun.jersey.core.spi.factory.ResponseImpl" que tiene su propia lógica para obtener StatusType. –

Cuestiones relacionadas