2010-07-12 26 views
28

Usando Spring 3, me gusta crear un manejador de excepciones mediante el ExceptionHandler anotación que se encargará de "ninguna página encontrada (404)" solicitudes. Estoy usando el siguiente código para hacer esto. Pero cuando señalo una URL que no existe, se invoca el manejador de excepciones predeterminado definido por Spring.Spring 3 - Crear ExceptionHandler para NoSuchRequestHandlingMethodException

Es posible que esté manejando la excepción NoSuchRequestHandlingMethodException. Si es así, ¿qué excepción debería estar registrando?

¿Podría echar un vistazo al siguiente código y ver lo que estoy haciendo mal?

NOTA: Si cambio la excepción en el @ExceptionHandler a NullPointerException y crear un RequestMapping a tirar puntero nulo, que va a funcionar.

import org.springframework.stereotype.Controller; 
    import org.springframework.web.bind.annotation.ExceptionHandler; 
    import org.springframework.web.bind.annotation.RequestMapping; 

    import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; 

    import org.apache.commons.logging.Log; 
    import org.apache.commons.logging.LogFactory; 
    import org.springframework.web.servlet.ModelAndView; 

    @Controller 
    public class GeneralHandler { 
     private final Log logger = LogFactory.getLog(getClass()); 

     @ExceptionHandler(NoSuchRequestHandlingMethodException.class) 
     public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) { 
     ModelAndView mav = new ModelAndView(); 
     logger.error("Exception found: " + ex); 
     return mav; 
     } 
    } 

Respuesta

41

@ExceptionHandler métodos -annotated se invocan cuando un método @RequestMapping en esa misma clase produce una excepción. Entonces, cuando agregaste la asignación que lanzó el NullPointerException, funcionó, ya que el método asignado y el manejador de excepciones estaban juntos en la misma clase.

Cuando no se encuentra una asignación, Spring no tiene forma de asociar el NoSuchRequestHandlingMethodException con su @ExceptionHandler, porque no llegó a igualar la solicitud a un método de controlador. Esto no se menciona explícitamente en los documentos, pero es el comportamiento que he observado.

Si desea manejar esta excepción especialmente, tendrá que usar la más general HandlerExceptionResolver approach, en lugar de la técnica más especializada @ExceptionHandler.

+2

Gracias. Utilizaré el enfoque HandlerExceptionResolver. – sgsweb

+0

¿funcionó para usted? Sigo teniendo el mismo problema – SJS

2

Puede ir con el enfoque this, es una idea genial y funciona, es necesario lanzar excepciones solo con un Handler particular que hace que @ExceptionHandler no sea tan útil como parece.

16

En primavera 3.2 se puede utilizar @ContollerAdvice tener una ExceptionHandler para todas sus controladores como este:

@ControllerAdvice 
public class GeneralHandler { 

    @ExceptionHandler 
    public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) { 
     ModelAndView mav = new ModelAndView(); 
     ... 
     return mav; 
    } 
} 

incluso se puede añadir más anotaciones para volver JSON serializado

@ExceptionHandler 
    @ResponseBody 
    @ResponseStatus(HttpStatus.BAD_REQUEST) 
    public RestError resolveBindingException (MethodArgumentNotValidException methodArgumentNotValidException, Locale locale) 
    { 
     BindingResult bindingResult = methodArgumentNotValidException.getBindingResult(); 
     return getRestError(bindingResult, locale); 
    } 
+0

Esto es más o menos lo que terminé haciendo, pero como también estaba usando ContentNegotiatingViewResolver, terminé atrapando 'Exception', luego envolviéndola en una clase con anotaciones de serialización JSON y XML y devolviéndola en lugar de ModelAndView, el cliente termina obteniendo la versión serializada del objeto contenedor. –

Cuestiones relacionadas