我正在使用 Jersey 流式传输“分块”输出,我的客户希望在流式传输时读取并显示部分结果。
这是我正在做的示例代码:
@Path("streaming")
public class StreamingResource {
@GET
@Produces("application/octet-stream")
public Response getStream() {
return Response.ok(new FeedReturnStreamingOutput()).build();
}
public static class FeedReturnStreamingOutput implements StreamingOutput {
@Override
public void write(OutputStream output)
throws IOException, WebApplicationException {
try {
for (int i = 0; i < 10; i++) {
output.write(String.format("Hello %d\n", i).getBytes());
output.flush();
TimeUnit.MILLISECONDS.sleep(500);
}
} catch (InterruptedException e) { throw new RuntimeException(e); }
}
}
}
如https://stackoverflow.com/a/34358215/2452569中所述,我必须像这样向我的服务器配置添加一个配置值,否则内容不会像写入的那样刷新:
public class AppConfig extends ResourceConfig {
public AppConfig() {
...
property(ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 0);
}
}
此 Jersey 服务器是大型商业应用程序的一部分,到目前为止,该应用程序还没有任何需要这种流式传输的端点。
由于
OUTBOUND_CONTENT_LENGTH_BUFFER
设置是服务器范围的设置,我担心将其设置为零会对我们的客户群产生负面影响。我在网上搜索了一下,试图找出那些可能是什么,但我很难辨别出任何具体的东西。
那么,有两个问题:
如果您想在 Jersey 中启用流式传输而不在服务器范围内设置
OUTBOUND_CONTENT_LENGTH_BUFFER
,请考虑使用 ContainerResponseFilter
在资源级别进行配置。这允许您自定义特定端点的缓冲行为。
使用
ContainerResponseFilter
的示例:
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import java.io.IOException;
public class StreamingResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
// Set the buffer size to zero for streaming
responseContext.getHeaders().putSingle("Content-Length", "0");
}
}
在您的 Jersey 应用程序中注册此过滤器:
import org.glassfish.jersey.server.ResourceConfig;
public class YourApplication extends ResourceConfig {
public YourApplication() {
// Register your resource classes
packages("your.package.name");
// Register the streaming response filter
register(StreamingResponseFilter.class);
}
}
将
OUTBOUND_CONTENT_LENGTH_BUFFER
设置为零可能会影响非流式响应的性能,因为缓冲被禁用。这可能会导致大型响应使用更高的内存,并可能影响整体系统性能。确保进行彻底的测试,特别是在具有大负载的场景中,以评估对您的特定应用程序的影响。
此外,某些客户端或网络设备可能需要内容长度标头,将其设置为零可能不符合 HTTP 规范。测试与不同客户端的兼容性并确保您的用例符合 HTTP 标准至关重要。
在生产环境中应用此类更改之前,始终在受控环境中进行全面测试,以减轻潜在问题。