2016-12-16 172 views
0

在Spring引导和休息应用程序中,我配置了一个异常处理程序,如下所示。如果在请求使其停止服务之后抛出异常,它会正常工作。Springboot异常处理程序不会捕获异常

剩下的api期望“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

你的类将仅捕捉来自控制器中出现的错误。您看到的错误发生在调用控制器之前,因为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

+0

谢谢亚当。这为找到一个可行的解决方案提供了非常好的指针,但我花了一段时间才解决它。看起来春天不喜欢两个异常处理程序。我有ExceptionHandlerExceptionResolver和ResponseEntityExceptionHandler因此异常总是要ResponseEntityExceptionHandler。我删除了ResponseEntity,并保留了全局的ExceptionHandlerExceptionResolver,它像一个魅力一样工作。 – Sannu

0

这里是最终的解决方案:

@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将忽略全局处理程序。