2013-01-23 48 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"/> 
相关问题