繁体   English   中英

如何在没有分块响应的纯Java项目中的Play框架中发送InputStream?

[英]How to send a InputStream in play framework in an java only project without chunked responses?

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

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

当查看默认的ok(file, ..)方法以返回File对象时,它会进入只能从scala访问的播放内部,并且使用甚至无法从外部访问的内部播放执行上下文。 如果它可以与InputStream一样工作,那就太好了。

FWIW,我现在找到了一种服务InputStream的方法,该方法基本上重复了Results.ok(File)方法允许直接传递到InputStream的逻辑。

关键是使用scala调用从InputStream创建一个枚举数: play.api.libs.iteratee.Enumerator$.MODULE$.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;
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM