Page和Ajax调用Spring异常处理

时间:2016-10-03 10:14:59

标签: ajax rest jsp spring-mvc

我经历了Spring exception handling documentation并且我没有理解如何处理ajax调用未处理的exeptions。

在一个应用程序中处理页面请求未处理异常和ajax调用未处理异常的方便方法是什么?

这可能是一个问题,因为全局异常处理程序也会捕获ajax调用并返回专用错误页面'有很多东西,因此阻止为ajax错误回调提供苗条的错误回复。

2 个答案:

答案 0 :(得分:2)

在休息控制器中有三种处理异常的方法:

使用@ResponseStatus和正确的HTTP结果代码注释您的异常,这些代码应在抛出给定异常时返回。

EG。如果抛出PersonNotFoundException,则将http 404返回给客户端(未找到)

@ResponseStatus(HttpStatus.NOT_FOUND)
public class PersonNotFoundException { … }

另一种方法是在控制器中使用@ExceptionHandler注释方法。在@ExceptionHandler注释的值中,您可以定义应捕获的异常。此外,您可以在同一方法上添加@ResponseStatus注释,以定义应将哪些HTTP结果代码返回给客户端。

@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler({PersonNotFoundException.class})
public void handlePersonNotFound() {
  ...
}

首选方法:将ResponseEntityExceptionHandler接口实现为@ControllerAdvice。这样,您可以将异常处理逻辑应用于具有集中异常处理的所有控制器。您可以在教程here中阅读更多内容。

@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    ...
    @Override
    protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        String unsupported = "Unsupported content type: " + ex.getContentType();
        String supported = "Supported content types: " + MediaType.toString(ex.getSupportedMediaTypes());
        ErrorMessage errorMessage = new ErrorMessage(unsupported, supported);
        return new ResponseEntity(errorMessage, headers, status);
    }
    ...
}

请注意,您不应对所有类型的异常返回通用500 - Internal server error。通常,您希望为客户端错误提供400s范围的结果 - 错误的请求。 500s范围的结果代码到服务器端错误。此外,最好根据发生的情况返回更具体的代码,而不仅仅是400或500.

答案 1 :(得分:0)

我接着解决了使用请求标头在全局异常处理程序中拆分ajax调用和序号页面请求的问题。对于ajax无效的用户输入类型的异常和内部服务器错误,也有不同的错误响应。

...
public class Application extends SpringBootServletInitializer {

@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
    SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
    r.setDefaultErrorView("forward:/errorController");
    return r;
}
@Controller
public class ErrorController {

    public static final Logger LOG = Logger.getLogger(ErrorController.class);

    @RequestMapping(value = "/errorController")
    public ModelAndView handleError(HttpServletRequest request,
            @RequestAttribute("exception") Throwable th) {

        ModelAndView mv = null;
        if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
            if (isBusinessException(th)) {
                mv = new ModelAndView("appAjaxBadRequest");
                mv.setStatus(BAD_REQUEST);
            } else {
                LOG.error("Internal server error while processing AJAX call.", th);
                mv = new ModelAndView("appAjaxInternalServerError");
                mv.setStatus(INTERNAL_SERVER_ERROR);
            }
            mv.addObject("message", getUserFriendlyErrorMessage(th).replaceAll("\r?\n", "<br/>"));
        } else {
            LOG.error("Cannot process http request.", th);
            mv = new ModelAndView("appErrorPage");
            mv.addObject("exeption", th);
        }

        return mv;
    }
}