2010-07-11 2 views
8

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

Siehe http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

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).

+1

Ich denke, Option 1 wird Ihre beste Wette sein – skaffman

Antwort

4

Java verwendet Ausnahmen, um solche Dinge auf natürliche Weise zu behandeln. Am Ende vereinfacht es im Allgemeinen Ihre Logik und verringert die Wahrscheinlichkeit, einen Fehler zu machen, indem Sie vergessen zu überprüfen, dass etwas einen Fehler hatte. Sie können die Fehlerlogik auch aus dem Hauptstrom des Codes entfernen.

Ich sehe nicht, warum der Fall, den Sie präsentieren, sich von jedem anderen Fall unterscheidet, in dem ich die Ausnahmebehandlung verwenden würde, um mit Fehlern umzugehen.

+0

Danke. Eine weitere Untersuchung der Ausnahmeroutine von Spring 3 zeigt, dass ich über die @ExceptionHandler-Annotation mit erhöhten Ausnahmen im Controller umgehen kann, da ich sie genauso behandeln kann wie eine Anfrage. Dies scheint mir ein bisschen netter als Versuch/Fang in der normalen Methode. –

+1

@Ben J: Ich bin mir nicht sicher, ob '@ ExceptionHandler' Methoden Zugriff auf das' BindingResult' haben. – skaffman