繁体   English   中英

如何使用 JAX-RS stream 一个无尽的 InputStream

[英]How to stream an endless InputStream with JAX-RS

我有一个包含一些数据的无尽InputStream ,我想返回这些数据以响应GET HTTP 请求。 我希望我的网络/API 客户端无休止地从中读取。 我如何使用 JAX-RS 做到这一点? 我正在尝试这个:

@GET
@Path("/stream")
@Produces(MediaType.TEXT_PLAIN)
public StreamingOutput stream() {
    final InputStream input = // get it
    return new StreamingOutput() {
        @Override
        public void write(OutputStream out) throws IOException {
            while (true) {
                out.write(input.read());
                out.flush();
            }
        }
    };
}

但内容不会出现在客户端。 但是,如果我添加OutputStream#close() ,服务器会在那一刻传送内容。 我怎样才能让它真正流式传输?

因此,您有刷新问题,您可以尝试按照规范中的说明获取 ServletResponse:

@Context 注释可用于指示对 Servlet 定义的资源的依赖。 基于 Servlet 的实现必须支持注入以下 Servlet 定义的类型:ServletConfig、ServletContext、HttpServletRequest 和 HttpServletResponse。

注入的 HttpServletResponse 允许资源方法在返回之前提交 HTTP 响应。 实现必须检查已提交的状态,并且仅在响应尚未提交时才处理返回值。

然后冲洗一切你可以,像这样:

@Context
private HttpServletResponse context;

@GET
@Path("/stream")
@Produces(MediaType.TEXT_PLAIN)
public String stream() {
    final InputStream input = // get it
    ServletOutputStream out = context.getOutputStream();
            while (true) {
                out.write(input.read());
                out.flush();
                context.flushBuffer();
            }
    return "";
}

只需使用 JAX-RS 的 StreamingOutput

@Path("/numbers")
public class NumbersResource {

    @GET
    public Response streamExample(){
        StreamingOutput stream = new StreamingOutput() {
            @Override
            public void write(OutputStream out) throws IOException, WebApplicationException {
                Writer writer = new BufferedWriter(new OutputStreamWriter(out));
                for (int i = 0; i < 10000000 ; i++){
                    writer.write(i + " ");
                }
                writer.flush();
            }
        };
        return Response.ok(stream).build();
    }
}

只是一个疯狂的猜测:

@GET
@Path("/stream")
@Produces(MediaType.TEXT_PLAIN)
public Response stream() {
    final InputStream input = getit();
    return Response.ok(input, MediaType.TEXT_PLAIN_TYPE).build();        
}

人们应该使用 Java 9 或更高版本可以使用transferTo将输入 stream 复制到 output stream 所以这样做:


@GET
@Path("/stream")
@Produces(MediaType.TEXT_PLAIN)
public StreamingOutput stream() {
    final InputStream input = // get it

        StreamingOutput stream = output -> {
            try {
                is.transferTo(output);
            }
            catch (Exception e) {
                throw new WebApplicationException(e);
            } finally {
                is.close();
            }
        };

        return Response.ok(stream, MediaType.APPLICATION_OCTET_STREAM).build();
    }

暂无
暂无

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

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