2010-07-12 217 views
28

使用Spring 3創建的ExceptionHandler,我喜歡創造使用的ExceptionHandler標註,將處理請求「發現(404)無頁」異常處理程序。我正在使用下面的代碼來做到這一點。但是,當我指向一個不存在的URL時,將調用Spring定義的默認異常處理程序。春季3 - 爲NoSuchRequestHandlingMethodException

可能是因爲我在處理NoSuchRequestHandlingMethodException異常。如果是,那麼我應該註冊什麼樣的例外?

請你看看下面的代碼,看看我做錯了什麼?

注:如果我改變例外的@ExceptionHandlerNullPointerException異常,並創建一個RequestMapping拋出空指針,將工作。當對同一類中的@RequestMapping方法拋出異常

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

回答

41

@ExceptionHandler -annotated方法被調用。因此,當你添加映射投擲NullPointerException,那工作,因爲映射的方法和異常處理程序在同一個類中。

當沒有找到映射時,Spring無法將NoSuchRequestHandlingMethodException@ExceptionHandler關聯,因爲它沒有將請求匹配到處理程序方法。這在文檔中沒有明確提及,但是我觀察到的行爲。

如果你想專門處理這個異常,你將不得不使用更通用的HandlerExceptionResolver approach,而不是更專業的@ExceptionHandler技術。

+2

謝謝。我將使用HandlerExceptionResolver方法。 – sgsweb 2010-07-12 19:28:26

+0

它適合你嗎?我仍然遇到同樣的問題 – SJS 2013-03-22 13:16:56

2

你可以用this的方法,這是個好主意和工作方式,只有使用特定的Handler才能拋出異常,這使得@ExceptionHandler不像看起來那麼有用。

16

在Spring 3.2,您可以使用@ContollerAdvice有一個的ExceptionHandler爲所有的控制器是這樣的:

@ControllerAdvice 
public class GeneralHandler { 

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

您甚至可以添加多個註釋返回序列化JSON

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

這幾乎是我最終做的事情,但是因爲我也在使用ContentNegotiatingViewResolver,所以我最終捕獲了'Exception',然後用JSON和XML序列化註釋將其包裝到一個類中,然後返回而不是ModelAndView,所以客戶端最終得到了包裝對象的序列化版本。 – 2013-02-08 11:58:55