You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:39:00