背景是获取Controller类输出的结果数据。
实现方案,使用@RestControllerAdvice+ResponseBodyAdvice接口。不能使用Interceptor,在执行Interceptor时,response已经提交。也可以考虑aspect方案,不过实现麻烦些,增加较多的代码,效率低。
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAndAdviceHandler implements ResponseBodyAdvice<Payload> {@ResponseStatus(HttpStatus.OK)@ExceptionHandler(RuntimeException.class)public Payload handleRuntimeException(RuntimeException ex) {log.error(ex.getMessage(), ex);return Payload.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage(), null);}@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {/*判断方法参数是否为Payload*/return returnType.getParameterType().isAssignableFrom(Payload.class);}@Overridepublic Payload beforeBodyWrite(Payload body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType,ServerHttpRequest request, ServerHttpResponse response) {/*日志输出body*/log.info("request.url={},response.data: {}",request.getURI().getPath(), JSON.toJSONString(body));return body;}
- Payload 类为Controller统一返回的参数
- 如果发生异常先执行handleRuntimeException再执行beforeBodyWrite
输出效果:
2024-04-17 17:35:00,925 INFO [http-nio-8080-exec-4] [00e8204cc30b4eb492185d410184745b] c.q.g.GlobalExceptionAndAdviceHandler request.url=/test/cnt/getReferenceAudio,response.data: {"code":500,"msg":"计算参考音频失败"}