web-dev-qa-db-ja.com

応答のJAX / Jerseyカスタムエラーコード

ジャージーでは、既知のステータスコードに関連付けられているステータス文字列を「置き換える」にはどうすればよいですか?

例えば.

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

以下を含むHTTP応答を生成します。

HTTP/1.1 401 Unauthorized

私(私ではありませんが、クライアントアプリケーション)は、応答を次のように表示したいと思います。

HTTP/1.1 401 Authorization Required

私は次のアプローチを試しましたが、無駄でした:

1)これはHTTP応答の本文に文字列を追加するだけです

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

2)これでも同じ結果:

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

あなたの助けに感謝!

-spd

23
user245717

ジャージーでこれを行うには、WebApplicationExceptionクラスの概念があります。 1つのメソッドは、このクラスとすべてのメソッドを単純に拡張して、返されるエラーテキストを設定することです。あなたの場合、これは次のようになります。

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

}

これで、RESTサービスを実装するコードで、このタイプの新しい例外をスローし、コンストラクターにテキスト値を渡すだけです。

throw new UnauthorizedException("Authorization Required");

これにより、Web例外ごとにこのようなクラスを作成し、同様の方法でスローできます。

これはJerseyユーザーガイドでも説明されていますが、コードは実際には少し間違っています。

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

38
jallch

よくわかりません JSR 339:JAX-RS 2.0:Java RESTful Webサービス用API はすでにこれをカバーしているかどうか。

このために Response.StatusType を拡張する必要があるかもしれません。

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

そして、ここにいくつかの拡張ステータスタイプがあります。

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

これが私のやり方です。

@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.
4
Jin Kwon