use*_*613 8 java spring spring-mvc spring-boot
我正在使用ExceptionAdvice和ResponseStatusException来处理我的网络应用程序中的异常情况。现在我想在抛出ResponseStatusException控制器类时记录异常信息。
我总是可以在 Controller 类中抛出异常的行附近编写日志代码:
controllerMethod(){
logger.error("some thing happens here!");
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "some reason");
}
Run Code Online (Sandbox Code Playgroud)
但是到处编写代码太乏味了,事实上,我想要一些我在课堂上使用的模式ExceptionAdvice:
@ResponseBody
@ExceptionHandler(MyException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
String myExceptionHandler(MyException e){
logger.error("oops!", e);
return "something";
}
Run Code Online (Sandbox Code Playgroud)
然而,ReponseStatusExceptionSpring 生成的响应具有我想要维护的格式,例如:
{
"timestamp": "2018-02-01T04:28:32.917+0000",
"status": 400,
"error": "Bad Request",
"message": "Provide correct Actor Id",
"path": "/actor/8/BradPitt"
}
Run Code Online (Sandbox Code Playgroud)
那么,无论如何,我是否可以使用建议类进行日志记录,ResponseStatusException同时仍保持其生成的响应,或者相反,使用其他类来添加日志功能,而无需在引发异常的任何地方键入ReponseStatusException?logger.error
您可以使用属性启用日志记录
spring.mvc.log-resolved-exception=true
Run Code Online (Sandbox Code Playgroud)
涉及的类有
这是一种方法(在 Spring Boot 2.3.3 中测试)。
创建一个扩展的类ResponseStatusExceptionResolver:
/**
* Extended implementation that adds logging of {@link ResponseStatusException}s.
* <p>
* Note: {@link #setMessageSource(MessageSource)} has to be called if reason is a message code, rather than a message itself
*/
private static class LoggingResponseStatusExceptionResolver extends ResponseStatusExceptionResolver {
@Override
protected ModelAndView resolveResponseStatus(ResponseStatus responseStatus, HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log(responseStatus.code(), responseStatus.reason(), ex);
return super.resolveResponseStatus(responseStatus, request, response, handler, ex);
}
@Override
protected ModelAndView resolveResponseStatusException(ResponseStatusException ex, HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log(ex.getStatus(), ex.getReason(), ex);
return super.resolveResponseStatusException(ex, request, response, handler);
}
private void log(HttpStatus status, String reason, Exception exception) {
if (status.isError()) {
logger.error(status + ": " + reason + "\n", exception);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的应用程序配置类之一中实现WebMvcConfigurer默认解析器并将其替换为扩展解析器:
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.replaceAll(resolver ->
resolver instanceof ResponseStatusExceptionResolver
? new LoggingResponseStatusExceptionResolver()
: resolver
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2753 次 |
| 最近记录: |