我想在Rest Spring引导应用程序中处理异常。我知道,使用@ControllerAdvice和ResponseEntity可以返回一个代表我的错误的自定义对象,但是我想要的是向所有正在发生的异常中添加新字段。
我创建了一个自定义Exception,该继承自带有一个额外属性(字符串列表)的RuntimeException:
@ResponseStatus(HttpStatus.CONFLICT) public class CustomException extends RuntimeException { private List<String> errors = new ArrayList<>(); public CustomException(List<String> errors) { this.errors = errors; } public CustomException(String message) { super(message); } public CustomException(String message, List<String> errors) { super(message); this.errors = errors; } public List<String> getErrors() { return errors; } public void setErrors(List<String> errors) { this.errors = errors; } }
在我的控制器中,我以这种方式抛出了这个自定义异常:
@GetMapping("/appointment") public List<Appointment> getAppointments() { List<String> errors = new ArrayList<>(); errors.add("Custom message"); throw new CustomException("This is my message", errors); }
当我用邮递员测试我的Rest端点时,似乎Spring Boot不会整理我的error字段,响应是:
{ "timestamp": "2017-06-05T18:19:03", "status": 409, "error": "Conflict", "exception": "com.htech.bimaristan.utils.CustomException", "message": "This is my message", "path": "/api/agenda/appointment" }
如果可以从异常中获取“ path”和“ timestamp”字段,则可以使用@ControllerAdvice来获取自定义对象,但是这两个属性没有获取器。
谢谢。
好!这是DefaultErrorAttributes中“ path”和“ timestamp”的实现,您也可以在自定义实现中实现:
路径:
String path = getAttribute(requestAttributes, "javax.servlet.error.request_uri"); if (path != null) { errorAttributes.put("path", path); }
时间戳记:
errorAttributes.put("timestamp", new Date());
有关Spring Boot中的错误定制的文档在这里。
@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); // customize here return errorAttributes; } }; }
或者,您可以编写一个自定义实现:
@Component public class CustomErrorAttributes extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) { Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace); // customize here return errorAttributes; } }
该ErrorAttributes豆定制的错误如下回应:
ErrorAttributes
{ "timestamp": 1413883870237, "status": 500, "error": "Internal Server Error", "exception": "org.example.ServiceException", "message": "somthing goes wrong", "path": "/index" }
该"exception"属性可以使用定制@ExceptionHandler。@ ControlerAdvice可以用于跨控制器自定义异常。要在控制器级别进行自定义,可以将它们放置在控制器中。
"exception"
@ExceptionHandler
ControlerAdvice
在您的情况下:
@ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Invalid Inputs") @ExceptionHandler(CustomException.class) private void errorHanlder() { //Log exception } public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) { Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace); Throwable error = getError(requestAttributes); if (error instanceof CustomException) { errorAttributes.put("errorList", ((CustomException)error).getErrors()); } return errorAttributes; }