在身体异常弹簧休息中添加新字段
Posted
技术标签:
【中文标题】在身体异常弹簧休息中添加新字段【英文标题】:Add new field in body exception spring rest 【发布时间】:2017-11-06 14:40:33 【问题描述】:我想在我的 Rest spring boot 应用程序中处理异常。我知道使用 @ControllerAdvice 和 ResponseEntity 我可以返回一个自定义对象来代表我的错误,但我想要的是在现有异常的主体中添加一个新字段。
我创建了一个自定义异常,它继承了带有额外属性的 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 没有编组我的错误字段,响应是:
"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"
如果我可以从异常中获取“路径”和“时间戳”字段,我可以使用 @ControllerAdvice 获取自定义对象,但是这两个属性没有 getter。
谢谢。
【问题讨论】:
【参考方案1】:好吧!这是 DefaultErrorAttributes 中“路径”和“时间戳”的实现,您也可以在自定义实现中实现:
路径:
String path = getAttribute(requestAttributes, "javax.servlet.error.request_uri");
if (path != null)
errorAttributes.put("path", path);
时间戳:
errorAttributes.put("timestamp", new Date());
spring boot 中错误定制的文档是here。
@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
bean 自定义错误响应如下:
"timestamp": 1413883870237,
"status": 500,
"error": "Internal Server Error",
"exception": "org.example.ServiceException",
"message": "somthing goes wrong",
"path": "/index"
"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;
【讨论】:
我尝试将此功能集成到我的控制器中,但每次调用我的端点时都会出现此异常:org.thymeleaf.exceptions.TemplateInputException: Error resolve template "generic/error", template任何配置的模板解析器可能不存在或可能无法访问 我认为您正在实现 REST 端点。所以,使用 ResponseEntity。 这个解决方案是我在问题帖子中谈到的。我可以使用它,但是如何从异常主体中获取路径和时间戳属性,以便我可以将它们添加到自定义错误对象中? 对不起!我忽略了。更新了答案。 谢谢@YuVi。方法errorAttributes应该在控制器类中声明吗?这个声明将为所有异常添加一个新的键值对,还是我应该在每个异常处理程序中单独自定义它?【参考方案2】:以前的答案确实有这一切,但不知何故我花了一段时间才弄明白,所以总的来说,实现这一点的最简单方法是拥有这样的 bean:
@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 CustomExceptionthere)
errorAttributes.put("errorList", ((CustomException)error).getErrors());
return errorAttributes;
;
【讨论】:
以上是关于在身体异常弹簧休息中添加新字段的主要内容,如果未能解决你的问题,请参考以下文章