46

Jersey を使用して構築された REST サービスがあります。

サーバーに送信された MIME に応じて、カスタム例外ライターの MIME を設定できるようにしたいと考えています。application/jsonjson を受信しapplication/xmlた場合、および xml を受信した場合に返されます。

今、私は をハードコーディングapplication/jsonしていますが、それは XML クライアントを暗闇の中に置き去りにしています。

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

現在のリクエストを取得するには、どのコンテキストを利用できますContent-Typeか?

ありがとう!


回答に基づいて更新

完全なソリューションに興味がある他の人のために:

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
}

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

ErrorResponseConverter はカスタム JAXB POJO です。

4

2 に答える 2

26

@ javax.ws.rs.core.Context javax.ws.rs.core.HttpHeadersフィールド/プロパティをルートリソースクラス、リソースメソッドパラメーター、またはカスタムjavax.ws.rs.ext.ExceptionMapperに追加してみてください。 HttpHeaders.getMediaType()を呼び出します。

于 2010-07-17T12:11:14.013 に答える
16

headers.getMediaType()は、Acceptヘッダーではなく、エンティティのメディアタイプで応答します。例外を変換する適切な方法は、Acceptヘッダーを使用して、クライアントが要求した形式で応答を取得できるようにすることです。上記の解決策を前提として、リクエストが次のようになっている場合(JSONはヘッダーを受け入れますが、XMLエンティティに注意してください)、XMLが返されます。

POST http:// localhost:8080 / service / giftcard / invoice?draft = true HTTP / 1.1
受け入れる:application / json
承認:基本dXNlcjp1c2Vy
コンテンツタイプ:application / xml
ユーザーエージェント:Jakarta Commons-HttpClient / 3.1
ホスト:localhost:8080
プロキシ接続:Keep-Alive
コンテンツの長さ:502
<?xml version = "1.0" encoding = "UTF-8" Standal = "yes"?> <sample> <node1> </ node1> </ sample>

正しい実装は、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();
}
于 2012-05-31T13:57:10.540 に答える