我在我的基于
Spring Boot的Rest服务中定义了一个全局异常处理:
@ControllerAdvice public class GlobalExceptionController { private final Logger LOG = LoggerFactory.getLogger(getClass()); @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR,reason = "Internal application error") @ExceptionHandler({ServiceException.class}) @ResponseBody public ServiceException serviceError(ServiceException e) { LOG.error("{}: {}",e.getErrorCode(),e.getMessage()); return e; } }
和一个自定义ServiceException:
public class ServiceException extends RuntimeException { private static final long serialVersionUID = -6502596312985405760L; private String errorCode; public ServiceException(String message,String errorCode,Throwable cause) { super(message,cause); this.errorCode = errorCode; } // other constructors,getter and setters omitted }
到目前为止这么好,当一个异常被触发时,控制器的工作原理和响应:
{ "timestamp": 1413883870237,"status": 500,"error": "Internal Server Error","exception": "org.example.ServiceException","message": "somthing goes wrong","path": "/index" }
但是字段errorCode不会显示在JSON响应中.
那么如何在我的应用程序中定义一个自定义异常响应.
解决方法
Spring Boot使用
ErrorAttributes
的实现来填充渲染为JSON的Map.默认情况下,使用
DefaultErrorAttributes
的实例.要包括您的自定义errorCode,您需要提供一个自定义的ErrorAttributes实现,该实现了解ServiceException及其错误代码.此自定义实现应该是您的配置中的@Bean.
一种方法是将DefaultErrorAttributes分类:
@Bean public ErrorAttributes errorAttributes() { return new DefaultErrorAttributes() { @Override public Map<String,Object> getErrorAttributes( RequestAttributes requestAttributes,boolean includeStackTrace) { Map<String,Object> errorAttributes = super.getErrorAttributes(requestAttributes,includeStackTrace); Throwable error = getError(requestAttributes); if (error instanceof ServiceException) { errorAttributes.put("errorCode",((ServiceException)error).getErrorCode()); } return errorAttributes; } }; }