我有一个要求,我需要从休息控制器返回一些状态/ 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方法。那么有效实现这一目标的方法是什么? 提前致谢
答案 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。确切地说,你需要
sendPushNotifiction
注释@Async
。@EnableAsync
注释一些配置类。sendPushNotifiction()
。执行流程不会等待sendPushNotifiction
完成。如果不起作用,请尝试在单独的服务中编写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);
}
});
}