Behandeln einer benutzerdefinierten Fehlerantwort in der JAX-RS 2.0-Clientbibliothek

Ich fange an, die Verwendung der neuen client-API-Bibliothek in JAX-RS und wirklich lieben es so weit. Ich fand eine Sache, die ich nicht herausfinden, jedoch. Die API die ich verwende ein benutzerdefiniertes format Fehlermeldung, die so aussieht wie diese zum Beispiel:

{
    "code": 400,
    "message": "This is a message which describes why there was a code 400."
} 

Gibt es 400 und der status, der code, sondern enthält auch eine beschreibende Fehlermeldung, Ihnen zu sagen, was Sie falsch gemacht haben.

Jedoch die JAX-RS 2.0-client ist re-mapping der 400-status in etwas generischer und ich verliere das gute Fehlermeldung. Es richtig Karten, die es zu einem BadRequestException, aber mit einem generischen "HTTP 400-Bad Request" - Meldung.

javax.ws.rs.BadRequestException: HTTP 400 Bad Request
    at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:908)
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:770)
    at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:90)
    at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:671)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:667)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:396)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:296)

Gibt es irgendeine Art von interceptor oder benutzerdefinierten error-handler, der injiziert werden kann, so dass ich Zugriff auf die echte Fehlermeldung. Ich habe auf der Suche durch Dokumentation, aber nicht sehen können, einen Weg, es zu tun.

Ich bin mit Jersey, aber ich habe versucht, diese mithilfe von CXF und bekam das gleiche Ergebnis. Hier ist, was der code aussieht.

Client client = ClientBuilder.newClient().register(JacksonFeature.class).register(GzipInterceptor.class);
WebTarget target = client.target("https://somesite.com").path("/api/test");
Invocation.Builder builder = target.request()
                                   .header("some_header", value)
                                   .accept(MediaType.APPLICATION_JSON_TYPE)
                                   .acceptEncoding("gzip");
MyEntity entity = builder.get(MyEntity.class);

UPDATE:

Ich die Lösung implementiert aufgeführt in den Kommentar unten. Es ist etwas anders, da sich die Klassen geändert haben, ein bisschen in die JAX-RS 2.0-client API. Ich denke immer noch, es ist falsch, dass das Standardverhalten zu geben, ist eine Allgemeine Fehlermeldung und verwerfen die Reale. Ich verstehe, warum es würde nicht analysieren meiner Fehler-Objekt, nicht aber das un-analysiert-version sollte zurückgegeben wurden. Ich am Ende mit dem replizieren Ausnahme mapping, dass die Bibliothek bereits tut.

Danke für die Hilfe.

Hier ist mein filter Klasse:

@Provider
public class ErrorResponseFilter implements ClientResponseFilter {

    private static ObjectMapper _MAPPER = new ObjectMapper();

    @Override
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
        //for non-200 response, deal with the custom error messages
        if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
            if (responseContext.hasEntity()) {
                //get the "real" error message
                ErrorResponse error = _MAPPER.readValue(responseContext.getEntityStream(), ErrorResponse.class);
                String message = error.getMessage();

                Response.Status status = Response.Status.fromStatusCode(responseContext.getStatus());
                WebApplicationException webAppException;
                switch (status) {
                    case BAD_REQUEST:
                        webAppException = new BadRequestException(message);
                        break;
                    case UNAUTHORIZED:
                        webAppException = new NotAuthorizedException(message);
                        break;
                    case FORBIDDEN:
                        webAppException = new ForbiddenException(message);
                        break;
                    case NOT_FOUND:
                        webAppException = new NotFoundException(message);
                        break;
                    case METHOD_NOT_ALLOWED:
                        webAppException = new NotAllowedException(message);
                        break;
                    case NOT_ACCEPTABLE:
                        webAppException = new NotAcceptableException(message);
                        break;
                    case UNSUPPORTED_MEDIA_TYPE:
                        webAppException = new NotSupportedException(message);
                        break;
                    case INTERNAL_SERVER_ERROR:
                        webAppException = new InternalServerErrorException(message);
                        break;
                    case SERVICE_UNAVAILABLE:
                        webAppException = new ServiceUnavailableException(message);
                        break;
                    default:
                        webAppException = new WebApplicationException(message);
                }

                throw webAppException;
            }
        }
    }
}

InformationsquelleAutor der Frage Chuck M | 2014-03-21

Schreibe einen Kommentar