在 Spring MVC 处理程序 returns 之后调用另一个方法

Call another method after Spring MVC handler returns

我有一个要求,我需要 return 来自休息控制器的一些 status/Long 值,然后执行代码以发送推送通知。

@RequestMapping(value="/create")
public String createTicket() throws InterruptedException {
    // code to create ticket
    return "ticket created";
    // need to call sendPushNotifiction() after I return status
}

    public void sendPushNotifiction() throws InterruptedException {
    // code to send push notification
    System.out.println("Sent push notification successfully!!");    
}

有人能告诉我如何实现吗?是否可以为此使用 Spring AOP?我认为线程不会保证仅在 return 之后执行 sendPushNotifiction 方法。那么有哪些方法可以有效地做到这一点呢? 提前致谢

创建另一个方法,首先调用 createTicket() 方法,然后调用 sendPushNotifiction() 方法。这样就可以了。这是我愚见中最简单的方法。

我同意 youngHobbit 的解决方案,你可以像下面那样做 wh

@RequestMapping(value="/create")
public String entryMethod() throws InterruptedException {
   String response = createTicket();
   sendPushNotifiction();
   return response ;
}

public String createTicket() throws InterruptedException {
    // code to create ticket
    return "ticket created";
    // need to call sendPushNotifiction() after I return status
}

    public void sendPushNotifiction() throws InterruptedException {
    // code to send push notification
    System.out.println("Sent push notification successfully!!");    
}

尽管另一个解决方案 可以是 forward/redirect 在完成第一个方法后请求另一个方法。但是如果它解决了你的目的,请采用第一种方法,因为它简单、清晰和可读

AOP 主要用于处理您希望跨应用程序处理的横切关注点,不应该像这样用于非常具体的目的。

为什么要引入额外的复杂性

你可以这样调用:

@RequestMapping(value="/create")
public void create(){
createTicket();
sendPushNotifiction();
}

public String createTicket() throws InterruptedException {
    // code to create ticket
    return "ticket created";
    // need to call sendPushNotifiction() after I return status
}

    public void sendPushNotifiction() throws InterruptedException {
    // code to send push notification
    System.out.println("Sent push notification successfully!!");    
}

createTicket()被spring.You调用不能调用它directly.You可以使用org.springframework.web.servlet.HandlerInterceptor。只需从[=15=调用你的sendPushNotifiction()方法] 或 afterCompletion() 的方法 你的 HandlerInterceptor

    package com.sample.interceptor;

   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;

   import org.springframework.web.servlet.HandlerInterceptor;
   import org.springframework.web.servlet.ModelAndView;

   public class NotifictionHandlerInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
    //do nothing
}

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

    //call your method here
    //call sendPushNotifiction()

}

}

并在 spring-mvc 上下文中注册您的处理程序

    <mvc:interceptors>
<bean class="com.sample.NotifictionHandlerInterceptor" />
   </mvc:interceptors>

另一种方法是将 sendPushNotification() 的执行推迟到某个线程/线程池。在return之前使用队列入队处理,然后在你的线程中出队处理。

但是,您应该注意 link 您对真实调用者的请求并注意失败等。

网上有很多例子。查找 java.util.concurrent 示例、执行程序、...

我认为这可能是异步处理的一个很好的用例。 Spring 对应 good support。准确地说,你需要

  1. @Async注释sendPushNotifiction
  2. @EnableAsync注释一些配置class。
  3. 在return语句之前调用sendPushNotifiction()。执行流程不会等待 sendPushNotifiction 完成。

如果它不起作用,请尝试在单独的服务中编码 sendPushNotifiction

HandlerInterceptor 是解决方案,但代码比预期的要复杂一些。这是一个代码建议,通过将整个解决方案放在一个 class:

中来简化它
@RequestMapping(value = "/create")
public String createTicket() throws InterruptedException {
    String ticket = "ticket created";
    result.set(ticket); // Save the ticket to be used after response
    return ticket;
}

public void sendPushNotifiction(String ticket) throws InterruptedException {
    System.out.println("Sent push notification successfully!!");
}

private static final ThreadLocal<String> result = new ThreadLocal<String>();

@Bean
public MappedInterceptor interceptor() {
    return new MappedInterceptor(Arrays.array("/create"), new HandlerInterceptor() {
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            // Get the saved object and clean for the next request
            String ticket = result.get();
            result.set(null);

            // Execute after response
            sendPushNotifiction(ticket);
        }
    });
}