Springboot异常处理程序不会捕获异常

时间:2016-12-16 19:36:26

标签: java rest spring-boot

在Spring启动和休息应用程序中,我已经配置了一个异常处理程序,如下所示。如果在请求使其休息服务后抛出异常,它可以正常工作。

Rest api期望Content-Type为“application / json”,如果我没有将该内容类型头发送到api,则异常处理程序不会捕获异常。它在日志中打印以下信息:

DEBUG [o.s.w.s.DispatcherServlet] DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/app/v1.0/customers/customer/zones/zoneName.]
DEBUG [o.s.w.s.m.m.a.RequestMappingHandlerMapping] Looking up handler method for path /app/v1.0/customers/customer/zones/zoneName.
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Invoking @ExceptionHandler method: public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)
DEBUG [o.s.w.s.DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG [o.s.w.s.DispatcherServlet] Successfully completed request

这是异常处理程序类:

@ControllerAdvice
@RestController  
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler
{

    @ExceptionHandler(Exception.class)  
    public final ResponseEntity<java.lang.Object> handleException(Throwable ex,WebRequest req)
    {
        ErrorResponse errorResponse = null;
        if (ex instanceof ApiException)
        {
            errorResponse = new ErrorResponse((ApiException) ex);
        }
        else
        {
            logger.error(ex);
            errorResponse = new ErrorResponse();
            errorResponse.setCode(HttpCodes.HTTP_CODE_500);
            errorResponse.setError(ex.getMessage());
        }
        return new ResponseEntity<Object>(errorResponse,
                HttpStatus.valueOf(errorResponse.getCode()));

    }
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex,
            HttpHeaders headers, HttpStatus status, WebRequest request)
    {
        Map<String, String> responseBody = new HashMap<String, String>();
        responseBody.put("path", request.getContextPath());
        responseBody.put("message",
                "The URL you have reached is not in service at this time (404).");
        return new ResponseEntity<Object>(responseBody, HttpStatus.NOT_FOUND);
    }
}

2 个答案:

答案 0 :(得分:2)

您的类只会捕获控制器内引发的错误。您看到的错误发生在调用控制器之前,因为Spring找不到控制器来处理请求。

DEBUG [o.s.w.s.m.m.a.RequestMappingHandlerMapping] Looking up handler method for path /app/v1.0/customers/customer/zones/zoneName.
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported

注意处理程序为空。

您还需要实现HandlerExceptionResolver来处理该类型的异常:http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

有关详细信息,请参阅Spring exception handler outside controller

答案 1 :(得分:1)

这是最终解决方案:

@ControllerAdvice  
public class SpringExceptionHandler extends ExceptionHandlerExceptionResolver
{
    @ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
    public ResponseEntity<Object> handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req)
    {
        ErrorResponse errorResponse = null;
        ex.printStackTrace();
        errorResponse = new ErrorResponse();
        errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
        errorResponse.setError(ex.getMessage());
        return new ResponseEntity<Object>(errorResponse,
            HttpStatus.valueOf(errorResponse.getCode()));
    }
}

现在我需要进行一些更改,使其适用于包括控制器抛出在内的所有异常,但这是为了以后。 (谢谢亚当)。

重要说明:如果有更多是全局处理程序和实体处理程序,则spring忽略全局处理程序。