2013-01-23 50 views
4

使用Spring,我有一個SimpleMappingExceptionResolver,它在resolveException方法中捕獲我的應用程序中的任何意外異常。在該方法中,我返回一個ModelAndView,它將錯誤消息文本返回給HTTP客戶端。下面的代碼:如何返回調用jQuery AJAX錯誤函數的錯誤消息和HTTP狀態代碼?

public class UnExpectedExceptionResolver extends SimpleMappingExceptionResolver { 

private Log logger = LogFactory.getLog(this.getClass().getName()); 
private ResourceBundleMessageSource messageSource; 

@Override 
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { 

    // let the end user know that an error occurred 
    Locale locale = RequestContextUtils.getLocale(request); 
    String messageText = messageSource.getMessage("systemError", null, locale); 
    Message message = new Message(messageText, MessageType.ERROR); 
    ModelAndView mav = new ModelAndView(); 
    mav.setView(new MappingJacksonJsonView()); 
    mav.addObject("message", message); 
    return mav; 
} 

這樣,響應被返回爲200的HTTP狀態代碼與響應文本爲消息(JSON)。不幸的是,客戶認爲這是一個有效的迴應,因爲200代碼,並試圖處理它。在

return mav; 

語句之前

response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Server Error"); 

:我嘗試設置HTTP狀態代碼500,如下所示。不幸的是,這返回一個HTML頁面,指示一個內部錯誤,而不是我的JSON消息。我怎樣才能返回JSON消息,並仍然向客戶端指出服務器錯誤(或某種類型的錯誤)?具體來說,我期望調用AJAX調用中的客戶端錯誤函數,並將消息數據發送回客戶端。僅供參考 - 我在客戶端使用jQuery。

+1

是否使用的是春天的版本?這是至關重要的:如果你只想要響應,Spring 3.1+似乎支持['@ ResponseBody'](http://stackoverflow.com/questions/5097134/spring-exceptionhandler-does-not-work-with-responsebody)狀態,你可以拋出一個用'@ ResponseStatus'裝飾的異常。如果你很幸運並且使用Spring 3.2,你可以返回[ResponseEntity](http://stackoverflow.com/questions/14247126/spring-mvc-controller-null-return-handler)。 –

+0

我使用Spring 3.0.5。它支持@ResponseBody。 – James

+0

是的,但不是在'@ExceptionHandler'註釋的方法。 Imho你應該考慮切換到Spring 3.2。如果有任何好的技術,那麼Spring團隊不會引入新的異常處理程序和控制器建議。 –

回答

0

下面的代碼添加到frontcontrol

@ExceptionHandler(Exception.class) 
public @ResponseBody 
MyErrorBean handleGeneralException(Exception e, 
     HttpServletRequest request, HttpServletResponse response) { 
    logger.info("Exception:" , e); 
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
    MyErrorBean errorBean = new MyErrorBean(); 
    errorBean.setStatus(MyConstants.ERROR_STATUS); 
    return errorBean; 

}` 

由於您使用JSON我相信你會在你的代碼配置一個MessageConverter,將它轉換爲JSON。通過設置狀態併發送一個bean,你將能夠解決它。

9

我不知道你是如何向服務器發送請求的。 但這是我的方式。

@ExceptionHandler(Exception.class) 
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "your message") 
public void handleException(IllegalStateException ex, HttpServletResponse response) throws IOException 
{ 
} 

在客戶端

$.ajax({ 
type : "POST", 
url : urlString, 
data : params, 
dataType : 'json', 
success : function(data) { 
    // do something} 
error: function (xhr, ajaxOptions, thrownError) { 
    alert(xhr.status); //This will be 500 
    alert(xhr.responseText); // your message 
    //do stuff 
    } 
+0

感謝您的回答。我正在通過jQuery ajax提出請求,正如你在答案中顯示的那樣。哪裏(哪個類)我會把handleException方法? – James

+0

取決於,如果你只有一個案例,你可以把它放在進行AJAX調用的控制器中。如果不寫一個所有其他控制器擴展的BaseController。因此,任何異常都會轉到該方法並返回500錯誤代碼。 – shazinltc

+0

params是什麼意思? – user3369592

6

在Spring 3.2,你可以把你的異常處理程序@ControllerAdvice註解類中。

@ControllerAdvice註釋可以包含@ExceptionHandler@InitBinder@ModelAttribute方法Spring 3.2 documenation

類和那些將適用於整個控制器層次@RequestMapping方法,而不是內聲明它們控制器層次。 @ControllerAdvice是一個組件註釋,允許通過類路徑掃描來自動檢測實現類。

所以,如果你的控制器通過自動掃描@Controller註釋類,@ControllerAdvice應該也可以拿起(如果掃描@Controller類有明確的標註表達式,您可能需要單獨註冊這個bean)。

@ControllerAdvice 
public class AppControllerAdvice{ 
     @ExceptionHandler(Throwable.class) 
     ResponseEntity<String> customHandler(Exception ex) { 
     return new ResponseEntity<String>(
       "Custom user message", 
       HttpStatus.INTERNAL_SERVER_ERROR); 

} 

請注意,該文本是返回實體的一部分,的HTTP原因短語。

+0

我喜歡這種方法最好。我爲各種異常收集了異常處理程序,並在我的控制器內部引發了真正的java異常。建議捕獲它們並將它們轉換爲適當的HTTP狀態代碼和消息。 – Jazzepi

4

這是我做到的。

public class CustomExceptionResolver extends AbstractHandlerExceptionResolver { 

    private static final Logger logger = Logger.getLogger(CustomExceptionResolver.class); 

    protected ModelAndView doResolveException(HttpServletRequest request, 
               HttpServletResponse response, 
               Object handler, 
               Exception ex) { 
     try { 
      response.reset(); 
      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
      response.setCharacterEncoding("UTF-8"); 
      response.setContentType("text/json"); 
      MappingJacksonJsonView view = new MappingJacksonJsonView(); 
      Map<String, String> asd = new HashMap<String, String>(); 
      asd.put("message", ex.getMessage()); 
      view.setAttributesMap(asd); 
      return new ModelAndView(view); 
     } catch (Exception e) { 
      logger.error("send back error status and message : " + ex.getMessage(), e); 
     } 
     return null; 
    } 

然後當然在我的JSON-servlet.xml文件:

<bean id="exceptionResolver" class="com.autolytix.common.web.CustomExceptionResolver"/> 
相關問題