2010-07-11 8 views
8

Editar: He mirado en @ExceptionHandler anotación y la combinación de esta primavera de 3 con la opción 1 a continuación parece ser una solución bastante limpio.errores que pasan de nuevo a la vista desde la capa de servicio

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

También he encontrado que esto es una buena lectura: http://blog.decaresystems.ie/index.php/2006/04/07/difficult-choices-in-handling-exceptions-in-enterprise-java-applications/


he desarrollado utilizando el marco Spring MVC desde hace algún tiempo, sin embargo estoy luchando para llegar a una 'buena' forma de pasar los errores que se generan en la capa de servicio a la JSP.

Básicamente, no creo que la lógica de negocios (más allá de "este campo sea obligatorio") deba estar en los Validadores, especialmente en cualquier lógica que requiera acceso a la base de datos. Entonces, lo que he estado haciendo es colocar una validación adicional y más complicada y una lógica comercial en la capa de servicio.

Por ejemplo, digamos que tengo una página que permite a un usuario comprar un libro. Hacen clic en "Comprar" en el JSP y el controlador llama al servicio para que todo suceda ... Ahora, ¿qué sucede si el servicio ve que no tienen fondos suficientes? ¿Cómo devuelvo este mensaje al JSP por lo que un pequeño y agradable El mensaje de "fondos insuficientes" puede mostrarse al usuario? He considerado dos maneras y no estoy seguro de que es correcta ...

Opción 1: Excepciones

La primera forma en que pensaba era elevar una excepción en la capa de servicio, que atrapan en el controlador y agregue un mensaje a BindingResult.

Servicio:

public void pay(Book book) throws InsufficientFundsException { 
    // Some logic goes here, which ends up throwing the above exception 
} 

controlador:

public ModelAndView(@ModelAttribute("book") Book book, BindingResult errors) { 
    try { 
     pay(book); 
    } catch (InsufficientFundsException ex) { 
     errors.reject("insufficient.funds"); 
    } 
    return new ModelAndView(blahblahblah); 
} 

Opción 2: Pass BindingResult a servicio de capa

La segunda manera era pasar el objeto BindingResult a la capa de servicio y elevar más errores en su contra.

Servicio:

public void pay(Book book, BindingResult errors) { 
    // User has insufficient funds, so... 
    errors.reject("insufficient.funds); 
} 

puedo ver problemas con estas dos maneras. La opción 1 se siente incómoda porque no solo tengo que atrapar la excepción, entonces tengo que agregar el error al resultado vinculante, así que parece que estoy haciendo lo mismo dos veces. Y la Opción 2 parece unir la capa de servicio demasiado cerca del controlador.

Finalmente, comprendo que no es el SimpleMappingExceptionResolver que podría ser utilizado en conjunción con la opción 1, pero no estoy seguro de lo apropiado que es (tal vez no he visto un ejemplo apropiado?). En el ejemplo anterior, digamos por razones de argumento que me gustaría que el usuario volviera al formulario original con un error rojo sobre el formulario, no redirigido a una página completamente diferente. SimpleMappingExceptionResolver me parece útil cuando desea redirigir a un usuario a una página de error estándar cuando se produce una excepción determinada (que no es exactamente lo que quiero saber cómo hacer).

+1

Creo que la opción 1 va a ser su mejor apuesta – skaffman

Respuesta

4

Java utiliza excepciones para manejar de forma natural este tipo de cosas. Al final, generalmente simplifica su lógica y reduce la posibilidad de cometer un error al olvidar comprobar que algo tuvo un error. También puede mover la lógica de error fuera del flujo principal del código.

No veo por qué el estuche que presenta es diferente de cualquier otro caso en el que usaría el manejo de excepciones para tratar los errores.

+0

Gracias. Investigaciones adicionales del controlador de excepciones de Spring 3 revelan que puedo manejar las excepciones planteadas en el controlador a través de la anotación @ExceptionHandler, ya que puedo tratarlo de la misma manera que lo haría con una solicitud. Esto para mí parece ser un poco más agradable que intentar capturar el método rqeuest normal. –

+1

@Ben J: aunque no estoy seguro si los métodos '@ExceptionHandler' tienen acceso al' BindingResult'. – skaffman

Cuestiones relacionadas