[英]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.