当前位置: 首页 > 知识库问答 >
问题:

如何发送一个输入流在发挥框架中的java只项目没有分块响应?

和季
2023-03-14

在Java(仅限)Play 2.3项目中,我们需要将InputStream的非分块响应直接发送到客户端。InputStream来自一个远程服务,我们希望从该服务直接流到客户端,而不阻塞或缓冲本地文件。因为我们在读取输入流之前就知道了大小,所以我们不想要分块的响应。

对于已知大小的输入流,返回结果的最佳方法是什么?(最好不使用Scala)。

查看默认的ok(文件,…) 返回文件对象的方法它深入到只能从scala访问的play内部,并使用甚至不能从外部访问的play内部执行上下文。如果它的工作原理相同就好了,只需要一个InputStream


共有1个答案

姜振濂
2023-03-14

FWIW我现在已经找到了一种方法来服务于一个输入流,它基本上重复了Results.ok(File)方法允许直接传递InputStream的逻辑。

关键是使用scala调用从InputStream创建枚举器:play。应用程序编程接口。libs。迭代尔。枚举数$。模块$。fromStream

private final MessageDispatcher fileServeContext = Akka.system().dispatchers().lookup("file-serve-context");

protected void serveInputStream(InputStream inputStream, String fileName, long contentLength) {
    response().setHeader(
            HttpHeaders.CONTENT_DISPOSITION,
            "attachment; filename=\"" + fileName + "\"");

    // Set Content-Type header based on file extension.
    scala.Option<String> contentType = MimeTypes.forFileName(fileName);
    if (contentType.isDefined()) {
        response().setHeader(CONTENT_TYPE, contentType.get());
    } else {
        response().setHeader(CONTENT_TYPE, ContentType.DEFAULT_BINARY.getMimeType());
    }

    response().setHeader(CONTENT_LENGTH, Long.toString(contentLength));

    return new WrappedScalaResult(new play.api.mvc.Result(

        new ResponseHeader(StatusCode.OK, toScalaMap(response().getHeaders())),

        // Enumerator.fromStream() will also close the input stream once it is done.
        play.api.libs.iteratee.Enumerator$.MODULE$.fromStream(
            inputStream,
            FILE_SERVE_CHUNK_SIZE,
            fileServeContext),

        play.api.mvc.HttpConnection.KeepAlive()));
}

/**
 * A simple Result which wraps a scala result so we can call it from our java controllers.
 */
private static class WrappedScalaResult implements Result {

    private play.api.mvc.Result scalaResult;

    public WrappedScalaResult(play.api.mvc.Result scalaResult) {
        this.scalaResult = scalaResult;
    }

    @Override
    public play.api.mvc.Result toScala() {
        return scalaResult;
    }

}
 类似资料:
  • 问题内容: 我写了一个视图来响应浏览器的ajax请求。它是这样写的- 我该怎么做? 这是我在客户端处理服务器响应的方式- 问题答案: 是专门用于呈现模板的快捷方式。如果您不想这样做,只需返回一个空值: 但是,在这种情况下,我不会这样做- 您正在向AJAX发送信号,指出存在错误,因此您应该返回错误响应(可能是代码400),而可以使用代替。

  • 问题内容: 我的目标是返回一个json对象,该对象将用于动态填充html代码中各种select语句中的选项。 所以我想从模型a抓取一个属性,从模型b抓取另一个,依此类推 那么我想要来自属性a和b以及c的所有值 作为键的JSON数组的值,因此 上面引用的帖子的这一部分很有意义: 这不是什么: 如何将单独的模型属性设置为正确的json键? 我假设它类似于序列化器关系,但是这些值不是通过一对一,一对一或

  • 我试图发送一个包含压缩(gzip)流输出的响应。我当前的代码是: 当我请求这项服务时,我的浏览器中会出现乱七八糟的数据。尽管我的响应正确设置了以下标题,但似乎我遗漏了什么:内容编码:gzip和传输编码:chunked。 在我的单元测试中,如果我提取主体并通过GzipInputStream()读取它,我就能够检索json主体。 当我更换时: 具有 val os=DeflaterOutputStrea

  • 问题内容: 我正在尝试创建一种控制台/终端,允许用户输入一个字符串,然后将其编入进程并打印出结果。就像普通的控制台一样。但是我在管理输入/输出流时遇到了麻烦。我已经研究了这个线程,但是可悲的是,该解决方案不适用于我的问题。 与标准命令(例如“ ipconfig”和“ cmd.exe”)一起,如果脚本要求输入,我还需要能够运行脚本并使用相同的输入流传递一些参数。 例如,在运行脚本“ python p

  • 问题内容: 我有一个Flask服务器,它从数据库中获取几个不同文件的二进制数据,并将它们放入python’zipfile’对象中。我想使用flask的“ send_file”方法将生成的zip文件与我的代码一起发送。 我最初能够通过使用BytesIO(bin)作为send_file的第一个参数来成功发送非zip文件,但是由于某些原因,我无法对生成的zip文件执行相同的操作。它给出了错误: ‘Zip

  • 我想将带有JSON对象的POST请求发送到指定的URL,但总是失败。 我已经检查了每个数据,以确保它们是正确的,但当我发送它们时,它们似乎被更改了,因此目标服务器无法正确处理我的请求。 我想这可能是appid中的错误。回复总是告诉我appid不正确,即使我百分之百确定它是正确的。下面是appid参数的格式:name:appid type:INT,但17位数字的INT完全超出范围。 响应:{“err