我需要创建一个java REST服务,它将输入流作为响应返回。我的问题是,在客户端收到整个流后,我不知道如何关闭流。我正在使用Java和CXF。感谢
@GET
@Path("/{uuid}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getAttachmentByUuid(@PathParam("uuid")String uuid)
{
//getting inputstream from AWS S3
InpputSream is=getStreamFromS3(uuid);
return Response.status(Response.Status.OK).entity(is).build();
// will this "is" stream causes memory leak,, do I have to close it. Client side is not controlled by me
}
答案 0 :(得分:2)
JAX-RS使用Java servlet实现。如果使用CXF CXFServlet
。您的流将使用servlet接口的HttpServletResponse
public void doGet(HttpServletRequest request, HttpServletResponse response)
如果您尚未创建流源,则不应关闭流源(HttpServletResponse
)。它是容器的责任,您可以干扰请求的生命周期
另见Is is necessary to close the input stream returned from HttpServletRequest?
答案 1 :(得分:1)
如果要关闭流,请考虑尝试使用资源:
@GET
@Path("/{uuid}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getAttachmentByUuid(@PathParam("uuid")String uuid)
{
//getting inputstream from AWS S3
// the try block opens the stream and guarantees to close it
try (InputStream is=getStreamFromS3(uuid)) {
return Response.status(Response.Status.OK).entity(from(is)).build();
}
}
这需要Java 7及更高版本。它也很棒!
如果您使用的是Java 6,那么您必须制作自己的finally块才能记住为您关闭流。
答案 2 :(得分:0)
您可能希望使用'Conduit' 有关详细信息,请参阅CXF Apache Custom Transport。 但要小心,文档说明:
如果物理协议支持,强烈建议不要在Conduit和Destination实现中断流。 CXF完全面向流式传输 - 它可以带来高性能和可扩展性。