2010-07-12 21 views
28

Utilizzando Spring 3, mi piace creare un gestore di eccezioni utilizzando il ExceptionHandler annotazione che gestirà "no pagina trovata (404)" richieste. Sto usando il seguente codice per fare questo. Ma quando indico un URL che non esiste, viene richiamato il gestore di eccezioni predefinito definito da Spring.Spring 3 - Creare ExceptionHandler per NoSuchRequestHandlingMethodException

Potrebbe essere che sto gestendo l'eccezione NoSuchRequestHandlingMethodException. Se lo è, allora quale eccezione dovrei registrare?

Volete dare un'occhiata al seguente codice e vedere cosa sto facendo male?

NOTA: Se cambio l'eccezione nel @ExceptionHandler a NullPointerException e creare un RequestMapping di gettare puntatore nullo, che funzionerà.

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; 
     } 
    } 

risposta

41

@ExceptionHandler metodi -annotated sono invocati quando un metodo @RequestMapping su quella stessa classe genera un'eccezione. Quindi, quando hai aggiunto la mappatura che ha gettato il NullPointerException, ha funzionato, dal momento che il metodo mappato e il gestore delle eccezioni erano insieme nella stessa classe.

Quando non viene trovata alcuna mappatura, Spring non ha modo di associare lo NoSuchRequestHandlingMethodException allo @ExceptionHandler, perché non è riuscito ad ottenere la corrispondenza tra la richiesta e il metodo del gestore. Questo non è menzionato esplicitamente nei documenti, ma è il comportamento che ho osservato.

Se si desidera gestire questa eccezione in particolare, è necessario utilizzare la più generale HandlerExceptionResolver approach, anziché la tecnica più specializzata @ExceptionHandler.

+2

Grazie. Userò l'approccio HandlerExceptionResolver. – sgsweb

+0

ha funzionato per te? Sto ancora avendo lo stesso problema – SJS

2

Si può andare con l'approccio this, è una grande idea e funziona, la necessità di lanciare eccezioni solo con un particolare Handler rende @ExceptionHandler non così utile come sembra.

16

In Primavera 3.2 è possibile utilizzare @ContollerAdvice di avere un ExceptionHandler per tutti i controller di questo tipo:

@ControllerAdvice 
public class GeneralHandler { 

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

È anche possibile aggiungere ulteriori annotazioni di restituire JSON serializzato

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

Questo è praticamente quello che ho finito, ma visto che stavo usando anche ContentNegotiatingViewResolver, ho finito per catturare 'Exception', quindi lo avevo inserito in una classe con annotazioni di serializzazione JSON e XML e restituito quello invece di ModelAndView, quindi il client ottiene la versione serializzata dell'oggetto wrapper. –

Problemi correlati