如何从HandlerInterceptor获取我的控制器的返回值

sin*_*ohe 5 spring spring-mvc

我正在为我的控制器创建一个日志管理器,记录其中的每个操作并返回值

我的控制器以这种方式定义:

@Controller
@RequestMapping(value="/ajax/user")
public class UserController extends AbstractController{
  @RequestMapping(value="/signup")
  public @ResponseBody ActionResponse signup(@Valid SignupModel sign) {
    ActionResponse response=new ActionRespone();
    response.setMessage("This is a test message");
    return response;
  }
}
Run Code Online (Sandbox Code Playgroud)

我定义了一个HandlerInterceptor来记录每个处理程序的输出:

@Component
public class ControllerInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        return true;
    }
  public void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {

      LogManager log=new LogManager();
      log.setMessage();//I need returned ActionResponse here
  }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

}
Run Code Online (Sandbox Code Playgroud)

我在哪里使用log.setMessage(); 我需要从注册方法返回的ActionResponse消息(这是测试消息)

我怎样才能做到这一点?

Bar*_*art 4

拦截器不是执行您想要的操作的正确位置,因为它无法获取处理程序的返回值。

使用面向方面编程 (AOP),您无需更改任何现有代码即可实现您想要的目标。为了在 spring 中工作,您需要包含 spring-aop 和 AspectJ 的 jar

创建方面和建议

@Aspect
@Component
public class ActionResponseLoggerAspect {

    private static final Logger logger = LoggerFactory.getLogger(ActionResponseLoggerAspect.class);
    
    @AfterReturning(pointcut="execution(* your.package.UserController.*(..)))", returning="result")
    public void afterReturning(JoinPoint joinPoint , Object result)  {
        
        if (result instanceof ActionResponse) {
            ActionResponse m = (ActionResponse) result;
            
            logger.info("ActionResponse returned with message [{}]", m.getMessage());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

每次控制器方法返回时都会执行afterReturning方法。

启用@AspectJ 支持

通过将其添加到 XML 配置来启用 AspectJ 支持。

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅 spring 文档