Java 如何在使用ResponseStatusException时记录异常信息

Java 如何在使用ResponseStatusException时记录异常信息,java,spring,spring-boot,spring-mvc,Java,Spring,Spring Boot,Spring Mvc,我正在使用ExceptionAdvice和ResponseStatusException来处理web应用程序中的异常情况。现在,我想在控制器类中抛出ResponseStatusException时记录异常信息 我总是可以在控制器类中引发异常的行附近编写日志代码: controllerMethod(){ logger.error(“这里发生了一些事情!”); 抛出新的ResponseStatusException(HttpStatus.FORBIDDEN,“某些原因”); } 但是到处写代码太单

我正在使用
ExceptionAdvice
ResponseStatusException
来处理web应用程序中的异常情况。现在,我想在控制器类中抛出
ResponseStatusException
时记录异常信息

我总是可以在控制器类中引发异常的行附近编写日志代码:

controllerMethod(){
logger.error(“这里发生了一些事情!”);
抛出新的ResponseStatusException(HttpStatus.FORBIDDEN,“某些原因”);
}
但是到处写代码太单调了,事实上,我想要一些我在
ExceptionAdvice
课程中使用的模式:

@ResponseBody
@ExceptionHandler(MyException.class)
@ResponseStatus(HttpStatus.禁止)
字符串myExceptionHandler(MyException e){
logger.error(“oops!”,e);
返回“某物”;
}
但是,Spring生成的
ReponseStatusException
响应具有我想要维护的格式,如:

{
    "timestamp": "2018-02-01T04:28:32.917+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Provide correct Actor Id",
    "path": "/actor/8/BradPitt"
}
那么,我是否可以使用advice类来记录
ResponseStatusException
,同时仍然保持其生成的响应,或者,对比一下,使用其他类在所有
ReponseStatusException
周围添加日志功能,而无需在引发异常的任何地方键入
logger.error

以下是一种方法(在Spring Boot 2.3.3中测试)

创建扩展
ResponseStatusExceptionResolver
的类:

/**
*添加{@link ResponseStatusException}日志记录的扩展实现。
*
*注意:如果原因是消息代码,而不是消息本身,则必须调用{@link#setMessageSource(MessageSource)}
*/
私有静态类LoggingResponseStatusExceptionResolver扩展ResponseStatusExceptionResolver{
@凌驾
受保护的ModelAndView resolveResponseStatus(ResponseStatus ResponseStatus、HttpServletRequest请求、HttpServletResponse响应、对象处理程序、异常ex)引发异常{
日志(responseStatus.code(),responseStatus.reason(),ex);
返回super.resolveresstatus(responseStatus,request,response,handler,ex);
}
@凌驾
受保护的ModelAndView resolveResponseStatusException(ResponseStatusException ex、HttpServletRequest请求、HttpServletResponse响应、对象处理程序)引发异常{
日志(例如getStatus(),例如getReason(),例如);
返回super.resolveResponseStatusException(例如,请求,响应,处理程序);
}
私有无效日志(HttpStatus状态、字符串原因、异常){
if(status.isError()){
错误(状态+”:“+原因+”\n”,异常);
}
}
}
然后在一个应用程序配置类中实现
webmvcconfiguer
,并用扩展的解析器替换默认解析器:

    @Override
    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        resolvers.replaceAll(resolver ->
                resolver instanceof ResponseStatusExceptionResolver
                        ? new LoggingResponseStatusExceptionResolver()
                        : resolver
        );
    }
@覆盖
public void extendHandlerExceptionResolver(列表解析程序){
解析程序.replaceAll(解析程序->
ResponseStatusExceptionResolver的解析程序实例
?新的LoggingResponseStatusExceptionResolver()
:解析器
);
}

您可以使用属性启用日志记录

spring.mvc.log-resolved-exception=true
涉及的课程包括

  • WebMvcAutoConfiguration
  • AbstractHandlerExceptionResolver
  • ResponseStatusExceptionResolver