背景是获取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);
}
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
/*判断方法参数是否为Payload*/
return returnType.getParameterType().isAssignableFrom(Payload.class);
}
@Override
public 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":"计算参考音频失败"}