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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube, Sie wollen, so etwas zu tun:
Andere Sache, die Sie ausprobieren können (da ich nicht weiß, wo diese API legt Zeug-d.h. in der Kopfzeile oder juristische Person oder was) ist:
Wenn Sie möchten, um in der Regel anzeigen REST-response-codes, Java-Ausnahme, die Sie hinzufügen können, eine client-filter zu tun:
In der oben genannten filter Sie können bestimmte Ausnahmen für jeden code oder erstellen Sie eine generische exception-Typ, die umschließt die Antwort-code und die Einheit.
InformationsquelleAutor der Antwort robert_difalco
Gibt es andere Möglichkeiten, um sich eine benutzerdefinierte Fehlermeldung für die Jersey-client neben dem schreiben eines benutzerdefinierten filter. (obwohl der filter ist eine ausgezeichnete Lösung)
1) Pass Fehlermeldung in einer HTTP-header-Feld.
Die detail-Fehlermeldung könnte in der JSON-Antwort und in einem zusätzlichen header-Feld, wie "x-Fehler-Meldung".
Den Server fügt der HTTP-error-header.
Den Client fängt die Ausnahme, NotFoundException in meinem Fall, und liest den response-header.
2) eine Andere Lösung ist, um die Ausnahme zu fangen und die Antwort Lesen von Inhalten.
InformationsquelleAutor der Antwort Peter Tarlos
Klasse WebApplicationException ausgelegt war, aber für einige Grund es ignoriert und überschreibt das, was Sie angeben, wie parameter für die Nachricht.
Deshalb habe ich meine eigene extension
WebAppException
ehrt, dass die patameters. Es ist eine einzige Klasse, und es erfordert keine Antwort filter oder mapper.Ich lieber die Ausnahmen als das erstellen einer Antwort, wie es ausgelöst werden kann von überall aus, die während der Bearbeitung.
Einfache Nutzung:
Den calss:
InformationsquelleAutor der Antwort Pla
Folgende Werke für mich
InformationsquelleAutor der Antwort Shivoam
Sehr viel präziser Lösung für alle stolpern auf dieser:
Aufrufen
.get(Class<T> responseType)
oder eine der anderen Methoden, die das Ergebnis geben Sie als argumentInvocation.Builder
wird einen Wert zurückgeben des gewünschten Typs anstelle einesResponse
. Als Nebeneffekt dieser Methoden wird überprüft, ob der empfangene status-code ist in der 2xx-Reihe und werfen einen geeignetenWebApplicationException
sonst.Aus der Dokumentation:
Dies ermöglicht es, fangen die
WebApplicationException
", " abrufen der aktuellenResponse
-, Prozess der enthaltenen Entität als Ausnahme-details (ApiExceptionInfo
) und wirft eine entsprechende exception (ApiException
).ApiExceptionInfo
ist benutzerdefinierten Datentyp in meiner Bewerbung:ApiException
ist, eigene exception-Typ in meine Anwendung:InformationsquelleAutor der Antwort toKrause