2010-01-07 9 views
21

Trong Jersey, làm cách nào chúng tôi có thể 'thay thế' chuỗi trạng thái được liên kết với mã trạng thái đã biết?Mã lỗi tùy chỉnh JAX/Jersey trong phản hồi

ví dụ:

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

tạo ra một phản ứng HTTP có chứa:

HTTP/1.1 401 Unauthorized 

I (không phải là tôi, nhưng ứng dụng client) muốn xem phản ứng như:

HTTP/1.1 401 Authorization Required 

Tôi đã thử các sau đây phương pháp tiếp cận nhưng vô ích:

1) Điều này chỉ thêm Chuỗi trong nội dung phản hồi HTTP

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

2) Tương tự kết quả với quá này:

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

Đánh giá cao sự giúp đỡ của bạn!

-spd

Trả lời

36

Để làm điều này ở Jersey bạn có khái niệm về lớp WebApplicationException. Một phương pháp đơn giản là mở rộng lớp này và tất cả một trong các phương thức để thiết lập văn bản lỗi được trả về. Trong trường hợp của bạn, điều này sẽ là:

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

} 

Bây giờ trong mã của bạn thực hiện dịch vụ còn lại, bạn chỉ cần ném ngoại lệ mới loại này, chuyển giá trị văn bản vào hàm tạo, ví dụ:

throw new UnauthorizedException("Authorization Required"); 

Điều đó có thể tạo một lớp như thế này cho mỗi ngoại lệ web của bạn và ném theo cách tương tự.

này cũng được giải thích trong hướng dẫn sử dụng Jersey - mặc dù đang thực sự hơi không chính xác:

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

+1

OP không hỏi cách khác với 'thực thể (thông điệp)'? –

+1

Đồng ý với @JinKwon, điều này khác với 1) trong câu hỏi của OP như thế nào? – TWiStErRob

4

Tôi không chắc chắn JSR 339: JAX-RS 2.0: The Java API for RESTful Web Services đã được bảo hiểm này hay không.

Bạn có thể phải gia hạn Response.StatusType cho việc này.

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

Và đây là một số loại statust mở rộng.

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

Đây là cách tôi làm.

@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

Tốt, cảm ơn bạn đã khiến tôi thấy rằng Trạng thái có giao diện mà tôi có thể gây rối! – TWiStErRob

+0

Cách tiếp cận này dường như không hoạt động với Jersey vì nó có một lớp "com.sun.jersey.core.spi.factory.ResponseImpl" có logic riêng của nó để lấy StatusType. –