在Spring mvc中传输响应

时间:2016-02-28 09:23:17

标签: rest spring-mvc asynchronous stream streaming

这就是情况,假设我有端点并接收一个请求,该请求在一段时间或任何时间之间检索数据,并且该请求的结果是我从数据库获取的一个大列表,让我们说一个列表一个"人"对象,然后对于每个人对象,我必须调用另一个方法,它可能有点慢,如果我必须等到它为这个大列表的所有元素执行它会延迟响应。

我想要完成的是我可以通过休息端点流式传输响应,而我的前端不必等到处理完所有这些列表后才开始在屏幕上显示它。

所以我在这里有一个困惑,我知道使用spring @Async的异步方法会让消费者即使任务仍未完成也能够给出响应,但据我所知,这是有助于发送电子邮件,或任何其他任务或一系列任务的响应,您将不会在屏幕上显示。

但是如果要在屏幕上显示响应的情况,我想我应该在我拥有一个完整的人物时立即传输一大块数据"对象准备好了

完成此任务的正确方法是什么?是在这种情况下的任何帮助的Async方法,或者我应该只找到一种方法来检测我何时形成一个人物对象流?或者我非常错误,我不理解异步和流媒体的概念。

一个小例子会有所帮助。

感谢。

1 个答案:

答案 0 :(得分:1)

我一直试图理解过去3天的相同概念,这是我的理解,可能对你有帮助。

异步REST端点:

如果您的REST端点正在执行一些复杂的业务逻辑或调用某些外部服务并且可能需要一些时间回复,那么最好从API ASAP回复将耗时的逻辑移到后台(单独的线程)。这是异步处理有用的地方。

分块输出:

如果您的终点预计会发送大量数据。为了改善用户体验,如果我决定在它们开始变为可用时开始渲染输出(在UI中),那么从REST端点开始的分块输出是更好的方法。

使用平针织物,我们可以实现异步处理和分块输出,如下面的示例所示。

public ChunkedOutput<String> getChunkedResponse() {
        final ChunkedOutput<String> output = new ChunkedOutput<String>(String.class);

        new Thread() {
            public void run() {
                try {
                    String chunk;
                    int index = 0;

                    while ((chunk = getWordAtIndex(index)) != null) {
                        output.write(chunk);
                        index++;
                    }
                } catch (IOException e) {
                    //Add code to handle the IO Exception during this operation
                } finally {
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        return output; // This output object may be returned way before output is created
    }

我已经尝试了一个样品,用平针织物和弹簧靴组合来测试它。您可以在我的git存储库here中查看它。

希望它有所帮助。