Spring MVC中如何在动作之前发送响应
问题内容:
假设我的弹簧控制器功能接收了大量数据。我要回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??
}
问题答案:
您当然可以在发送响应后进行处理。更通用的方法是使用的afterCompletion
方法HandlerInterceptor
。通过构造,它将在将响应发送给客户端之后执行,但是它迫使您将逻辑分为两个部分:控制器中的
前 部分和拦截器中的 后 部分。
另一种方法是忘记Spring MVC机制,并在控制器中手动提交响应:
@RequestMapping(value = Connectors.CONNECTOR_HEARTBEAT, method = RequestMethod.POST)
public void doSomething(@RequestBody List<Message> messages, HttpServletResponse response) {
int code = (messages!=null && !messages.isEmpty()) ? HttpServletResponse.SC_OK
: HttpServletResponse.SC_NOT_FOUND;
if (code != HttpServletResponse.SC_OK) {
response.sendError(code, res);
return;
}
java.io.PrintWriter wr = response.getWriter();
response.setStatus(code);
wr.print(res);
wr.flush();
wr.close();
// Now it it time to do the long processing
...
}
注意void返回代码,以通知Spring响应已在控制器中提交。
作为一个附带好处,处理仍在同一线程中进行,因此您可以完全访问会话范围的属性或Spring MVC或Spring Security使用的任何其他线程局部变量。