Edit: Ich ausgesehen habe in dem Frühling 3 @ExceptionHandler
Annotation und die Kombination dieses mit Option 1 sieht unten eine ziemlich saubere Lösung.Passing Fehler zurück in die Ansicht von der Dienstschicht
ich auch dies eine gute Lektüre zu sein gefunden: http://blog.decaresystems.ie/index.php/2006/04/07/difficult-choices-in-handling-exceptions-in-enterprise-java-applications/
ich die Spring MVC Framework seit einiger Zeit jedoch verwendet haben die Entwicklung Ich kämpfe mit einem kommen 'schöne' Möglichkeit, Fehler, die in der Service-Schicht ausgelöst werden, an die JSP weiterzuleiten.
Grundsätzlich glaube ich nicht, dass Geschäftslogik (außer "dieses Feld ist obligatorisch") in den Validatoren sein sollte, insbesondere jede Logik, die Zugriff auf die DB erfordert. Also, was ich getan habe, ist, weitere, kompliziertere Validierung und Geschäftslogik in die Service-Schicht zu bringen.
Zum Beispiel sagen wir, ich habe eine Seite, die es einem Benutzer ermöglicht, ein Buch zu kaufen. Sie klicken auf der JSP auf "Purchase" und der Controller ruft den Dienst an, um alles zu ermöglichen ... Was passiert jetzt, wenn der Dienst sieht, dass er nicht genug Geld hat - wie bekomme ich diese Nachricht zurück an die JSP, so ein nettes kleines "Unzureichende Mittel" Nachricht kann dem Benutzer angezeigt werden? Ich habe zwei Möglichkeiten in Betracht gezogen, und ich bin nicht sicher, was richtig ist ...
Option 1: Ausnahmen
Der erste Weg, ich dachte, war eine Ausnahme in der Dienstschicht zu erhöhen, falle es in der Controller und fügen Sie dem BindingResult eine Nachricht hinzu.
Service:
public void pay(Book book) throws InsufficientFundsException {
// Some logic goes here, which ends up throwing the above exception
}
Controller:
public ModelAndView(@ModelAttribute("book") Book book, BindingResult errors) {
try {
pay(book);
} catch (InsufficientFundsException ex) {
errors.reject("insufficient.funds");
}
return new ModelAndView(blahblahblah);
}
Option 2: Pass BindingResult Service-Schicht
Der zweite Weg, um die BindingResult Objekt der Dienstschicht zu passieren war und hebe weitere Fehler dagegen auf.
Service:
public void pay(Book book, BindingResult errors) {
// User has insufficient funds, so...
errors.reject("insufficient.funds);
}
kann ich Probleme mit diesen beiden Möglichkeiten sehen. Option 1 fühlt sich peinlich an, weil ich nicht nur die Ausnahme abfangen muss, sondern den Fehler zum Bindungsergebnis hinzufügen muss, so dass es sich anfühlt, als würde ich zweimal dasselbe tun. Und Option 2 scheint die Serviceschicht zu stark an den Controller zu binden.
Schließlich, ich weiß, es ist die SimpleMappingExceptionResolver
, die 1 in Verbindung mit Option verwendet werden könnte, aber ich bin nicht sicher, wie es angemessen ist (vielleicht habe ich kein gutes Beispiel gesehen?). Im obigen Beispiel sagen wir nur um des Arguments willen, dass ich möchte, dass der Benutzer mit einem roten Fehler über dem Formular zum ursprünglichen Formular zurückkehrt und nicht auf eine völlig andere Seite umgeleitet wird. Der SimpleMappingExceptionResolver scheint mir nützlich zu sein, wenn Sie einen Benutzer auf eine Standardfehlerseite umleiten möchten, wenn eine bestimmte Ausnahme ausgelöst wird (was nicht ganz das ist, was ich wissen möchte).
Ich denke, Option 1 wird Ihre beste Wette sein – skaffman