Ich lerne JAX-RS (auch bekannt als JSR-311) mit Jersey. Ich habe erfolgreich eine Root-Ressource erstellt und spiele mit Parametern herum:
@Path("/hello")
public class HelloWorldResource {
@GET
@Produces("text/html")
public String get(
@QueryParam("name") String name,
@QueryParam("birthDate") Date birthDate) {
// Return a greeting with the name and age
}
}
Dies funktioniert hervorragend und verarbeitet alle Formate im aktuellen Gebietsschema, die vom Konstruktor Date (String) verstanden werden (z. B. JJJJ / MM / TT und MM / TT / JJJJ). Wenn ich jedoch einen Wert gebe, der ungültig ist oder nicht verstanden wird, erhalte ich eine Antwort 404.
Beispielsweise:
GET /hello?name=Mark&birthDate=X
404 Not Found
Wie kann ich dieses Verhalten anpassen? Vielleicht ein anderer Antwortcode (wahrscheinlich "400 Bad Request")? Was ist mit der Protokollierung eines Fehlers? Fügen Sie möglicherweise eine Beschreibung des Problems ("schlechtes Datumsformat") in einen benutzerdefinierten Header ein, um die Fehlerbehebung zu erleichtern. Oder eine vollständige Fehlerantwort mit Details und einem 5xx-Statuscode zurückgeben?
ExceptionMapper
Schnittstelle (die besser ist als die Erweiterung). Weitere Informationen finden SieErstellen Sie über Klasse. Dies behandelt 404 (NotFoundException) und hier in der toResponse-Methode können Sie Ihre benutzerdefinierte Antwort geben. Ebenso gibt es ParamException usw., die Sie zuordnen müssten, um benutzerdefinierte Antworten bereitzustellen.
quelle
Jersey löst eine com.sun.jersey.api.ParamException aus, wenn die Parameter nicht freigegeben werden können. Eine Lösung besteht darin, einen ExceptionMapper zu erstellen, der diese Arten von Ausnahmen behandelt:
quelle
Sie können auch eine wiederverwendbare Klasse für mit QueryParam annotierte Variablen schreiben
dann benutze es so:
Obwohl die Fehlerbehandlung in diesem Fall trivial ist (eine 400-Antwort wird ausgelöst), können Sie mit dieser Klasse die Parameterbehandlung im Allgemeinen herausrechnen, einschließlich Protokollierung usw.
quelle
DateParam
oben genannte, die einorg.joda.time.DateTime
statt einschließtjava.util.Calendar
. Sie verwenden das@QueryParam
eher mit als mit sichDateTime
selbst.JodaModule
, die mit derObjectMapper
registerModules
Methode registriert werden kann. Es kann alle Konvertierungen vom Typ Joda verarbeiten.com.fasterxml.jackson.datatype.joda.JodaModule
Eine naheliegende Lösung: Nehmen Sie einen String auf und konvertieren Sie ihn selbst in Date. Auf diese Weise können Sie das gewünschte Format definieren, Ausnahmen abfangen und den gesendeten Fehler entweder erneut auslösen oder anpassen. Für das Parsen sollte SimpleDateFormat einwandfrei funktionieren.
Ich bin mir sicher, dass es auch Möglichkeiten gibt, Handler für Datentypen zu verknüpfen, aber vielleicht ist in diesem Fall nur ein bisschen einfacher Code erforderlich.
quelle
Ich mag auch StaxMan auch, dass StaxMan dieses QueryParam wahrscheinlich als String implementieren und dann die Konvertierung durchführen und bei Bedarf erneut würde.
Wenn das länderspezifische Verhalten das gewünschte und erwartete Verhalten ist, würden Sie Folgendes verwenden, um den Fehler 400 BAD REQUEST zurückzugeben:
throw new WebApplicationException(Response.Status.BAD_REQUEST);
Weitere Optionen finden Sie im JavaDoc für javax.ws.rs.core.Response.Status .
quelle
@QueryParam Dokumentation sagt
Wenn Sie steuern möchten, welche Antwort an den Benutzer gesendet wird, wenn der Abfrageparameter in String-Form nicht in Ihren Typ T konvertiert werden kann, können Sie WebApplicationException auslösen. Dropwizard enthält die folgenden * Param-Klassen, die Sie für Ihre Anforderungen verwenden können.
BooleanParam, DateTimeParam, IntParam, LongParam, LocalDateParam, NonEmptyStringParam, UUIDParam. Sehen https://github.com/dropwizard/dropwizard/tree/master/dropwizard-jersey/src/main/java/io/dropwizard/jersey/params
Wenn Sie Joda DateTime benötigen, verwenden Sie einfach den Dropwizard DateTimeParam .
Wenn die obige Liste nicht Ihren Anforderungen entspricht, definieren Sie Ihre eigene, indem Sie AbstractParam erweitern. Analysemethode überschreiben. Wenn Sie die Kontrolle über den Fehlerantworttext benötigen, überschreiben Sie die Fehlermethode.
Ein guter Artikel von Coda Hale dazu ist unter http://codahale.com/what-makes-jersey-interesting-parameter-classes/
Der Datumskonstruktor (String arg) ist veraltet. Ich würde Java 8-Datumsklassen verwenden, wenn Sie Java 8 verwenden. Andernfalls wird eine joda-Datumszeit empfohlen.
quelle
Dies ist eigentlich das richtige Verhalten. Jersey wird versuchen, einen Handler für Ihre Eingabe zu finden und aus der bereitgestellten Eingabe ein Objekt zu erstellen. In diesem Fall wird versucht, ein neues Date-Objekt mit dem Wert X zu erstellen, der dem Konstruktor bereitgestellt wird. Da dies ein ungültiges Datum ist, gibt Jersey gemäß Konvention 404 zurück.
Was Sie tun können, ist, das Geburtsdatum neu zu schreiben und als Zeichenfolge zu setzen. Versuchen Sie dann zu analysieren. Wenn Sie nicht das bekommen, was Sie wollen, können Sie jede gewünschte Ausnahme über einen der Ausnahmezuordnungsmechanismen auslösen (es gibt mehrere ).
quelle
Ich stand vor dem gleichen Problem.
Ich wollte alle Fehler an einem zentralen Ort erfassen und transformieren.
Es folgt der Code, wie ich damit umgegangen bin.
Erstellen Sie die folgende Klasse, die implementiert
ExceptionMapper
und hinzugefügt wird@Provider
diese Klasse Anmerkungen versehen. Dadurch werden alle Ausnahmen behandelt.Überschreiben Sie die
toResponse
Methode und geben Sie das Antwortobjekt zurück, das mit benutzerdefinierten Daten gefüllt ist.quelle
Ansatz 1: Durch Erweitern der WebApplicationException-Klasse
Erstellen Sie eine neue Ausnahme, indem Sie WebApplicationException erweitern
Wirf jetzt bei Bedarf 'RestException'.
Die vollständige Bewerbung finden Sie unter diesem Link .
Ansatz 2: Implementieren Sie ExceptionMapper
Der folgende Mapper behandelt die Ausnahme vom Typ 'DataNotFoundException'.
Die vollständige Bewerbung finden Sie unter diesem Link .
quelle
Nur als Erweiterung zu @Steven Lavine Antwort für den Fall, dass Sie das Browser-Anmeldefenster öffnen möchten. Es fiel mir schwer, die Antwort ( MDN-HTTP-Authentifizierung) ordnungsgemäß zurückzugeben ) vom Filter falls der Benutzer noch nicht authentifiziert war
Dies hat mir geholfen, die Antwort zu erstellen, um die Browser-Anmeldung zu erzwingen. Beachten Sie die zusätzliche Änderung der Header. Dadurch wird der Statuscode auf 401 gesetzt und der Header festgelegt, der den Browser veranlasst, das Dialogfeld Benutzername / Passwort zu öffnen.
quelle