假设我的弹簧控制器功能接收到大量数据。 我想返回200 OK,假设数据结构正确,之后我想要执行处理,这可能需要一段时间。
据我了解,发送响应的唯一方法是通过 return 命令。但我不想结束响应发送功能。
是否还有其他方法可以在功能中间向客户端发送响应?
创建一个新的线程运行是显而易见的,但其他语言(JS)可以让你更优雅地处理它。
@RequestMapping(value = Connectors.CONNECTOR_HEARTBEAT, method = RequestMethod.POST)
public ResponseEntity<String> doSomething(@RequestBody List<Message> messages) {
HttpStatus code = (messages!=null && !messages.isEmpty()) ? HttpStatus.OK
: HttpStatus.NOT_FOUND;
return new ResponseEntity<String>(res, code);
// how do I add code here??
}
答案 0 :(得分:8)
您当然可以在发送回复后进行处理。更一般的方法是使用afterCompletion
的{{1}}方法。通过构造,它将在响应发送到客户端后执行,但它会强制您在控制器中之前部分中的2个组件中拆分逻辑,之后的部分在拦截器中。
另一种方法是忘记Spring MVC机制并在控制器中手动提交响应:
HandlerInterceptor
请注意void返回代码,以通知Spring响应已在控制器中提交。
作为一个优势,处理仍然发生在同一个线程中,因此您可以完全访问会话作用域属性或Spring MVC或Spring Security使用的任何其他线程局部变量...
答案 1 :(得分:2)
我猜你会使用spring的异步机制 servlet 3.0中引入了异步方法,Spring为它们提供了一些支持 基本上......你提出要求;请求由服务器处理,然后在后台,新线程管理请求数据 这是一个有用的链接(至少我希望:))http://spring.io/blog/2012/05/10/spring-mvc-3-2-preview-making-a-controller-method-asynchronous/
答案 2 :(得分:0)
您应该使用HandlerInterceptor
。但是代码比预期的要复杂得多。所以,这里有一个代码建议,通过将整个解决方案放在一个类中来简化它:
@RequestMapping(value = Connectors.CONNECTOR_HEARTBEAT, method = RequestMethod.POST)
public ResponseEntity<String> doSomething(@RequestBody List<Message> messages) {
HttpStatus code = (messages!=null && !messages.isEmpty()) ? HttpStatus.OK
: HttpStatus.NOT_FOUND;
result.set(res); // Save the object to be used after response
return new ResponseEntity<String>(res, code);
}
private static final ThreadLocal<String> result = new ThreadLocal<String>();
@Bean
public HandlerInterceptor interceptor() {
return 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 res = result.get();
result.set(null);
// TODO Your code to be executed after response.
}
};
}
答案 3 :(得分:0)
您可以使用@Async
@RequestMapping(value = Connectors.CONNECTOR_HEARTBEAT, method =
RequestMethod.POST)
public ResponseEntity<String> doSomething(@RequestBody List<Message>
messages) {
do();
HttpStatus code = (messages!=null && !messages.isEmpty()) ? HttpStatus.OK
: HttpStatus.NOT_FOUND;
return new ResponseEntity<String>(res, code);
}
@Async
void do(){
//your code
}
在Java 8中可以正常工作
答案 4 :(得分:-2)
返回语句后不能有代码。试试这个:
@RequestMapping(value = Connectors.CONNECTOR_HEARTBEAT, method = RequestMethod.POST)
public ResponseEntity<String> doSomething(@RequestBody List<Message> messages) {
HttpStatus code = (messages!=null && !messages.isEmpty()) ? HttpStatus.OK
: HttpStatus.NOT_FOUND;
ResponseEntity<String> response = new ResponseEntity<String>(res, code);
// code here
return respone
}