2012-03-28 20 views
14

Possiedo un controller MVC Spring con alcune semplici richieste di servizio REST. Vorrei aggiungere un po 'di gestione degli errori quando vengono lanciate eccezioni specifiche dai miei servizi, ma non riesco a ottenere un metodo di gestione annotato con @ExceptionHandler per essere mai chiamato. Ecco un servizio sto deliberatamente lanciando un'eccezione per cercare di ottenere il mio metodo gestore di prendere in consegna. Il metodo del gestore non viene mai richiamato e Spring restituisce appena un errore 500 al client chiamante. Hai qualche idea su cosa sto facendo male?Spring MVC Metodo @ExceptionHandler nel controller mai richiamato

@ExceptionHandler(IOException.class) 
public ModelAndView handleIOException(IOException ex, HttpServletRequest request, HttpServletResponse response) { 
    response.sendError(HttpServletResponse.SC_FORBIDDEN); 
    System.out.println("It worked!"); 
    return new ModelAndView(); 
} 

@RequestMapping(value = "/json/remove-service/{id}", method = RequestMethod.DELETE) 
public void remove(@PathVariable("id") Long id) throws IOException { 
    throw new IOException("The handler should take over from here!"); 
} 

risposta

13

Questo tip on the Spring forum possono aiutare.

Probabilmente è stato configurato i fagioli per il tuo DispatchServlet in un file webmvc-servlet.xml (il file * -servlet.xml può essere un nome diverso)

Se il file XML include già un altro ExceptionResolver (come SimpleMappingExceptionResovler primavera wont aggiungere automaticamente tutti gli altri risolutori per voi aggiungendo così manualmente il risolutore di annotazione in questo modo:..

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver" /> 

dovrebbe consentire l'elaborazione @HandlerException

+3

'AnnotationMethodHandlerExceptionResolver' è ora deprecato, quindi questo non aiuta nelle versioni più recenti di Spring. –

+0

Utilizzando questo bean con la proprietà 'p: order' impostata sulla massima priorità (1) gestita per risolvere il mio problema. – Alex

+0

@MattFriedman Sostituendo semplicemente 'AnnotationMethodHandlerExceptionResolver' con' org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver' ha funzionato per me –

0

Non funzionerà, perché quando si restituisce String si ritorna Visualizza nome.

Ora il controller Spring MVC è alla ricerca di questo metodo è mai chiamato! Perchè no?! guarda e puoi trovare.

Assicurarsi che @ExceptionHandler viene mappata a vista esistente.

+0

che molto probabilmente risultato in una 404, non un 500. – skaffman

+1

Siamo spiacenti, il punto è che il metodo non viene mai chiamato, quindi ciò che viene restituito è irrilevante. Ho cambiato ciò che viene restituito. – 11101101b

12

Anche io ne ho sofferto. Ho scoperto che se si implementa erroneamente Throwable invece di Exception resolver eccezione sarà solo rigenerare il vostro Throwable come IllegalStateException. Ciò non riuscirà a richiamare il tuo @ExceptionHandler.

Se hai implementato Throwable invece di Exception prova a cambiarlo in Exception invece.

Ecco il codice in questione da InvocableHandlerMethod

catch (InvocationTargetException e) { 
      // Unwrap for HandlerExceptionResolvers ... 
      Throwable targetException = e.getTargetException(); 
      if (targetException instanceof RuntimeException) { 
       throw (RuntimeException) targetException; 
      } 
      else if (targetException instanceof Error) { 
       throw (Error) targetException; 
      } 
      else if (targetException instanceof Exception) { 
       throw (Exception) targetException; 
      } 
      else { 
       String msg = getInvocationErrorMessage("Failed to invoke controller method", args); 
       throw new IllegalStateException(msg, targetException); 
      } 
     } 
4

ho scoperto che @ExceptionHandler opere con Throwable Quando si definisce il metodo in modo tale:

@ExceptionHandler(Throwable.class) 
@ResponseBody 
public String handleException(Throwable e) { 

} 

In questo metodo dei casi ha un solo argomento di tipo Throwable. Se provo a utilizzare in questo metodo alcuni parametri aggiuntivi (ho provato ad usare Model), ricevo 500 eccezioni (questo metodo non è call). Tuttavia, questo funziona ancora quando i parametri aggiuntivi sono HttpServlerRequest o HttpServlerResponse.

Problemi correlati