【问题标题】:How To Stream Text Response From a Java Spring MVC 3.0 Webapp如何从 Java Spring MVC 3.0 Webapp 流式传输文本响应
【发布时间】:2012-07-06 00:03:52
【问题描述】:

如何将文本输出流式传输到浏览器上的页面以显示可能需要大约 15 到 20 秒的操作进度?我已经尝试直接写入HttpServletResponse 的输出流,但用户仍然看到完整的输出整个过程完成后。

这是我迄今为止尝试过的

 @RequestMapping(value = "/test")
 public void test(HttpServletResponse response)
            throws IOException, InterruptedException {
    response.getOutputStream().println("Hello");
    response.getOutputStream().flush();
    Thread.sleep(2000);
    response.getOutputStream().println("How");
    response.getOutputStream().flush();
    Thread.sleep(2000);
    response.getOutputStream().println("are");
    response.getOutputStream().flush();
    Thread.sleep(2000);
    response.getOutputStream().println("you");
    response.getOutputStream().flush();
}

【问题讨论】:

  • 您是否尝试过在每次发送数据后刷新输出流?
  • @Luciano 我已经将我迄今为止尝试过的内容添加到了问题中。当我从 Chrome 查看页面时,这不起作用
  • 我认为你最好的选择是另一种方法:在 javascript 中使用一个计时器,它使用 ajax 每 1 秒(或半秒)从 /test 获取数据,并且 /test 将返回任何没有'在调用它之前没有被发送。
  • @Luciano 你建议的是我的后备计划,无论如何我可能最终都会使用它。但是,如果我的问题有一个有效的答案,我可以看到这是在没有异步作业执行器和状态管理的情况下完成的,我觉得这会更优雅。
  • 您也可以尝试使用 Web 套接字,但这需要对您的应用程序进行更多更改。

标签: java servlets spring-mvc


【解决方案1】:

我不是 Spring MVC 专家,但我认为您会执行类似发送“已接受”的 202 响应代码之类的操作,这表明服务器已收到请求并将进行一些异步处理。通常,服务器会提供一个 URL 以允许客户端发出有关操作状态的请求。您尝试做的事情违反了服务器/客户端关系的通常工作方式。客户端调用服务器,服务器响应然后关闭连接。您在什么情况下尝试这样做,出于什么原因?或许我可以提供一些更深入的见解或考虑另一种方法?

【讨论】:

  • 感谢您的关注!基本上,我想为用户提供请求执行作业的能力,能够监控进度并在作业完成后更新他的视图。我可以通过使作业执行程序异步并在session 中维护一些状态并从 UI 轮询来了解如何做到这一点。 但是如果我的问题有一个有效的答案,我可以看到这是在没有异步执行器和状态管理的情况下完成的。
  • 我觉得你要求的是服务器联系客户端,虽然不是不可能,但它会非常不规则。显然,有一些路由可以将信息以分块的数量发送回客户端(如 FTP),但不幸的是,我知道这是否适用于您想要做的事情,也不知道 Spring MVC 是否可行。祝你好运!
  • 谢谢!我可能会采用您和其他人现在提到的投票方法,并暂时保持这个问题的开放性。我只是喜欢探索所有的可能性。干杯!
【解决方案2】:

尝试使用:

response.flushBuffer();

正如 JavaDoc 所说:

强制将缓冲区中的任何内容写入客户端。调用此方法会自动提交响应,这意味着将写入状态代码和标头。

【讨论】:

    【解决方案3】:

    在使用 Chrome 进行测试时,这对我有用

    response.setBufferSize(0);
    response.setContentType("text/event-stream");
    
    ... write content ...
    

    【讨论】:

      【解决方案4】:
      @Controller
      public class MyController{
      
          @RequestMapping(value = "/test", method = RequestMethod.GET)
          public @ResponseBody String getTest() {
            return "hello how are you";
          }
      }
      

      如果您使用的是 spring 控制器,您可以使用响应正文注释执行上述操作。

      【讨论】:

      • @SeanPatrickFloyd 哦,对了,我没看到/读到那一点。这有点难......不确定
      猜你喜欢
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多