通过重写DefaultErrorAttributes
类的getErrorAttributes
方法,实现自定义异常返回字段;文中示例代码只适用于SpringBoot对外提供Restful形式接口,并且响应个格式是json,并非view和api接口混合形式应用,请根据实际情况做以修改。
需求
在接口发生错误时(如:参数不正确、数据不存在、系统异常),响应信息中增加transactionId
,用于后期与接入方进行日志查找。
解决方案
1.使用AOP对controller方法进行切面处理,该方法可以实现,但不是本文的重点,这里不介绍。
2.使用@ControllerAdvice
进行异常统一管理,但由于项目中有很多自定义异常,一旦再增加自定义异常,就要修改ControllerAdvice的方法,所以不是最佳选择。
3.继承DefaultErrorAttributes
,重写 getErrorAttributes
方法,一劳永逸。
在实际业务中有这样一个自定一异常:
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class IllegalArgumentException extends java.lang.IllegalArgumentException {
public IllegalArgumentException(String message) {
super(message);
}
}
当参数不正确时,抛出该异常:
if (type==''){
throw new IllegalArgumentException("invalid type value:" + type);
}
SpringBoot默认错误返回:
{
"timestamp": "2019-04-26T04:22:23.961+0000",
"status": 400,
"error": "Bad Request",
"message": "invalid type value : ",
"path": "/test"
}
根据需求,我们定义自己的ErrorAttribute 并继承 SpringBoot 的DefaultErrorAttributes
,重写getErrorAttributes
方法,通过调用父类的getErrorAttribute
方法,获得默认错误信息,再根据需求添加字段;如果需要记录error日志,可以通过父类getError
方法获得异常信息:
// org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
@Component
@Slf4j
public class MyCustomErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest,
boolean includeStackTrace) {
String uuid = UUID.randomUUID().toString();
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
errorAttributes.put("transactionId", uuid);
Throwable throwable = getError(webRequest);
if (throwable != null) {
log.error(uuid, throwable);
}
return errorAttributes;
}
}
再次运行程序,错误信息返回变成:
{
"timestamp": "2019-04-26T04:56:46.000+0000",
"status": 400,
"error": "Bad Request",
"message": "invalid type value : ",
"path": "/test",
"transactionId": "a6a263b2-9753-4a41-b873-778d5c24cf8c"
}
[…] 具体实现方法可参考SpringBoot的Restful接口异常返回增加字段 […]