在Spring MVC处理程序返回后调用另一个方法

时间:2015-10-17 07:29:57

标签: spring spring-mvc spring-aop

我有一个要求,我需要从休息控制器返回一些状态/ 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?我不认为线程只会在返回后保证执行sendPushNotifiction方法。那么有效实现这一目标的方法是什么? 提前致谢

7 个答案:

答案 0 :(得分:1)

创建另一个首先调用createTicket()方法然后调用sendPushNotifiction()的方法。那将完成这项工作。这是我认为最简单的方法。

答案 1 :(得分:1)

春天会调用

createTicket()。您无法直接调用它。您可以使用org.springframework.web.servlet.HandlerInterceptor。只需从sendPushNotifiction()或{{postHandle()调用afterCompletion()方法即可。 1}}方法 你的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 context

中注册处理程序
    <mvc:interceptors>
<bean class="com.sample.NotifictionHandlerInterceptor" />
   </mvc:interceptors>

答案 2 :(得分:1)

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

  1. 使用sendPushNotifiction注释@Async
  2. 使用@EnableAsync注释一些配置类。
  3. 在return语句前调用sendPushNotifiction()。执行流程不会等待sendPushNotifiction完成。
  4. 如果不起作用,请尝试在单独的服务中编写sendPushNotifiction

答案 3 :(得分:0)

我同意youngHobbit解决方案,您可以在下面执行此操作

@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!!");    
}

虽然另一种解决方案可以在完成第一个方法后将请求转发/重定向到另一个方法。但如果它解决了你的目的简单,清晰和可读,那么采取第一种方法

AOP主要用于处理您希望跨应用程序处理的横切问题,不应该用于这样的非常特定的目的。

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

答案 4 :(得分:0)

你可以这样打电话:

@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!!");    
}

答案 5 :(得分:0)

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

但是,您应该注意将您的请求链接到真正的来电者并处理失败等。

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

答案 6 :(得分:0)

HandlerInterceptor是解决方案,但代码比预期的要复杂一些。这里有一个代码建议,通过将整个解决方案放在一个类中来简化它:

@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);
        }
    });
}