Spring中ResponseBodyAdvice如何获取调用的RestController类名?
如何在ResponseBodyAdvice中获取RestController类名并记录响应日志
当然可以获取到对应的RestController类名!Spring给我们提供了足够的上下文信息来实现这个需求,下面我给你两种常用的实现方式:
方式一:通过MethodParameter直接获取
在ResponseBodyAdvice的beforeBodyWrite方法中,参数MethodParameter returnType包含了当前处理方法的元信息,我们可以通过它直接拿到方法所属的类:
@ControllerAdvice public class ResponseLoggingAdvice implements ResponseBodyAdvice<Object> { private static final Logger log = LoggerFactory.getLogger(ResponseLoggingAdvice.class); @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { // 只处理带有@RestController注解的类的方法 return returnType.getContainingClass().isAnnotationPresent(RestController.class); } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 获取RestController的简单类名(比如UserController) String controllerName = returnType.getContainingClass().getSimpleName(); // 若需要全限定类名(比如com.example.controller.UserController),用getName()即可 // String fullControllerName = returnType.getContainingClass().getName(); log.info("RestController [{}] 处理请求后返回: {}", controllerName, body); return body; } }
这种方式简单直接,但要注意:如果你的Controller方法是继承自父类或者接口,returnType.getContainingClass()拿到的是定义该方法的类,而不是实际的Controller子类。如果你的项目存在这种方法继承的场景,可以用下面的方式。
方式二:通过RequestContext获取实际的HandlerMethod
我们可以从请求上下文中拿到实际处理请求的HandlerMethod,从而获取到实例化的Controller类:
@ControllerAdvice public class ResponseLoggingAdvice implements ResponseBodyAdvice<Object> { private static final Logger log = LoggerFactory.getLogger(ResponseLoggingAdvice.class); @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { return true; // 可根据业务需求添加过滤规则 } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 从请求属性中获取HandlerMethod HandlerMethod handlerMethod = (HandlerMethod) ((ServletServerHttpRequest) request).getServletRequest() .getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE); if (handlerMethod != null && handlerMethod.getBeanType().isAnnotationPresent(RestController.class)) { String controllerName = handlerMethod.getBeanType().getSimpleName(); log.info("RestController [{}] 返回响应内容: {}", controllerName, body); } return body; } }
这种方式能确保拿到的是实际处理请求的Controller子类,适合存在方法继承的复杂场景。
两种方式都能满足你记录日志并添加Controller类名的需求,你可以根据自己的项目情况选择~
内容的提问来源于stack exchange,提问作者Ulrich
相关产品推荐
相关产品推荐

