如何返回调用jQueryAjax错误函数的错误消息和HTTP状态代码?

如何返回调用jQueryAjax错误函数的错误消息和HTTP状态代码?,jquery,ajax,spring,exception,http-status-codes,Jquery,Ajax,Spring,Exception,Http Status Codes,使用Spring,我有一个SimpleMappingExceptionResolver,它在resolveException方法中捕获应用程序中的任何意外异常。在该方法中,我返回一个ModelAndView,它将错误消息文本返回给HTTP客户端。代码如下: public class UnExpectedExceptionResolver extends SimpleMappingExceptionResolver { private Log logger = LogFactory.getLog

使用Spring,我有一个SimpleMappingExceptionResolver,它在resolveException方法中捕获应用程序中的任何意外异常。在该方法中,我返回一个ModelAndView,它将错误消息文本返回给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;
}
因此,返回的响应的HTTP状态代码为200,响应文本为消息(JSON)。不幸的是,由于200代码,客户机认为这是一个有效的响应,并试图以此方式处理它。我尝试将HTTP状态代码设置为500,如下所示:

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

 return mav;

声明。不幸的是,这将返回一个指示内部错误的HTML页面,而不是我的JSON消息。如何返回JSON消息并仍然向客户端指示服务器错误(或某种类型的错误)?具体来说,我希望调用AJAX调用中的客户机错误函数,并且仍然将消息数据发送回客户机。仅供参考-我正在客户端使用jQuery。

将以下代码添加到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,您将能够解决这个问题。

我不知道您到底是如何向服务器发出请求的。 但我会这样做

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

在Spring3.2中,您可以将异常处理程序放在
@ControllerAdvice
注释类中

@ControllerAdvice
注释的类可以包含
@ExceptionHandler
@InitBinder
@modeldattribute
方法,这些方法将应用于跨控制器层次结构的
@RequestMapping
方法,而不是在其中声明它们的控制器层次结构
@ControllerAdvice
是一个组件注释,允许通过类路径扫描自动检测实现类

因此,如果通过自动扫描
@Controller
注释类拾取控制器,
@ControllerAdvice
也应该可以工作(如果使用显式注释表达式扫描
@Controller
类,则可能需要单独注册此bean)

@ControllerAdvice
公共类AppControllerAdvice{
@ExceptionHandler(Throwable.class)
ResponseEntity customHandler(异常示例){
返回新响应(
“自定义用户消息”,
HttpStatus.INTERNAL_SERVER_ERROR);
} 
请注意,文本是返回实体的一部分,而不是HTTP原因短语。

我是这样做的

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;
    }
公共类CustomExceptionResolver扩展了AbstractHandlerExceptionResolver{
私有静态最终记录器Logger=Logger.getLogger(CustomExceptionResolver.class);
受保护的模型和视图doResolveException(HttpServletRequest,
HttpServletResponse,
对象处理程序,
例外情况(ex){
试一试{
response.reset();
response.setStatus(HttpServletResponse.SC_内部_服务器_错误);
响应。setCharacterEncoding(“UTF-8”);
setContentType(“text/json”);
MappingJacksonJsonView=新建MappingJacksonJsonView();
Map asd=newhashmap();
asd.put(“message”,例如getMessage());
view.setAttributeMap(asd);
返回新模型和视图(视图);
}捕获(例外e){
logger.error(“发回错误状态和消息:”+ex.getMessage(),e);
}
返回null;
}
当然,在我的json-servlet.xml文件中:

<bean id="exceptionResolver" class="com.autolytix.common.web.CustomExceptionResolver"/>


您使用的是哪个版本的Spring?这很重要:Spring 3.1+似乎支持,如果您只需要响应状态,您可以抛出一个用
@ResponseStatus
修饰的异常。如果您运气好,可以使用Spring 3.2返回。我使用的是Spring 3.0.5。它支持@ResponseBody.yes,但不在'@ExceptionHandler'中你应该考虑切换到Spring 3.2。如果有什么好的技术,那么Spring团队不会引入新的异常处理程序和控制器建议。谢谢你的建议。我已经切换到Spring 3.2。我查看了你的“响应实体”和“@响应体”链接(以及下面的答案)。。似乎我必须在每个控制器中放置异常处理程序方法。我如何使用ResponseEntity,使异常处理程序存在于一个类中,并像SimpleMappingExceptionResolver那样捕获来自所有控制器的任何意外异常?如果您能使用Spring 3.2提供答案,我将不胜感激。谢谢我通过jQueryAjax发出请求,正如您在回答中所示。Where(哪个类)我会使用handleException方法吗?这取决于,如果您只有一个case,您可以将它放在进行AJAX调用的控制器中。如果不编写一个BaseController,则所有其他控制器都会扩展它。因此,任何异常都会转到该方法并返回500个错误代码。params是什么意思?@user3369592:它是的json表示形式您想要发送的值我最喜欢这种方法。我有一个用于各种异常的异常处理程序集合,在我的控制器中我抛出真正的java异常。建议捕获它们并将它们转换为适当的HTTP状态代码和消息。
<bean id="exceptionResolver" class="com.autolytix.common.web.CustomExceptionResolver"/>