当前位置: 首页 > 知识库问答 >
问题:

作为响应实体的Jersey-StreamingOutput

沈长恨
2023-03-14
@GET
@Path("xxxxx")
@Produces(BulkConstants.TEXT_XML_MEDIA_TYPE})   
public Response getFile() {

    FeedReturnStreamingOutput sout = new FeedReturnStreamingOutput();
    response = Response.ok(sout).build();
    return response;
}

class FeedReturnStreamingOutput implements StreamingOutput {

    public FeedReturnStreamingOutput()

    @Override
    public void write(OutputStream outputStream)  {
        //write into Output Stream
    }
}

问题是,尽管在调用FeedReturnStreamingOutput之前从资源发回响应,但Jersey客户端会等待FeedReturnStreamingOutput执行完成。

客户端代码:

Client client = Client.create();

ClientResponse response = webResource
    //headers
    .get(ClientResponse.class);

//The codes underneath executes after FeedReturnStreamingOutput is executed which undermines the necessity of streaming

OutputStream os = new FileOutputStream("c:\\test\\feedoutput5.txt");
System.out.println(new Date() + " : Reached point A");

if (response.getStatus() == 200) {
    System.out.println(new Date() + " : Reached point B");
    InputStream io = response.getEntityInputStream();

    byte[] buff = new byte[1024000];
    int count = 0;

    while ((count = io.read(buff, 0, buff.length)) != -1) {
        os.write(buff, 0, count);
    }

    os.close();
    io.close();

} else {
    System.out.println("Response code :" + response.getStatus());
}

System.out.println("Time taken -->> "+(System.currentTimeMillis()-startTime)+" ms");

共有1个答案

段干弘毅
2023-03-14

问题在于缓冲OutputStream,Jersey用来缓冲实体以确定内容长度头。缓冲区的大小默认为8 KB。如果需要,可以禁用缓冲,或者只使用属性更改缓冲区的大小

serverproperties.outbound_content_length_buffer

一个整数值,定义用于缓冲服务器端响应实体的缓冲区大小,以便确定其大小并设置HTTP“Content-Length”标头的值。

默认值为8192。

这里有一个例子

@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); }
        }
    }
}

以下是未设置属性的结果

public class AppConfig extends ResourceConfig {
    public AppConfig() {
        ...
        property(ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 0);
    }
}
 类似资料:
  • 我使用的是Spring版本4(Spring data),我想将Object作为JSON返回,我想知道以下代码即使不使用xmlRootElement注释用户类也能工作: 任何机构都可以解释吗?当我需要注释要返回为JSON的对象类时,响应体/响应实体是否自己完成工作?

  • 我在雄猫上部署了一个泽西岛 2.5.1 应用程序。我在我的网络中添加了以下配置.xml: 它打印请求和响应头。但是,它没有在响应中打印请求/响应实体/主体。 我试着和不同的情妇玩,但没有运气,比如: 感谢您的回答。看起来我在上面粘贴了错误的配置。这是我在我的网络上有什么.xml: 它记录标题。但它不记录实体。这是我在日志中看到的: 我的Jersey应用程序部署在Tomcat 7_50服务器上。 如

  • 我正在从jsp调用一个endpoint: 它返回对象类型。 来自我想将响应保存在该对象中,以便解析查询结果。 错误: 问:这是保存ResultSet响应的正确方法吗?

  • 我可以使用toEntity()方法返回ResponseEntity,如下所示: 但是我想在返回之前处理响应头。上面的代码将WebClient响应转换为响应实体并立即返回,但我想将其存储在响应实体变量中,处理它,然后返回响应实体。 我提到了这个- 当我试图将其存储在varibale中时,我遇到了这个错误-

  • 我正在学习fetch(),发现响应的主体使用了一种叫做readableStream的东西。根据我的研究,readable stream允许我们在从服务器下载数据后开始使用它(我希望我是正确的:)。就fetch()而言,可读流如何与fetch()配合使用,也就是说,我们无论如何都需要下载所有数据,然后开始使用它。总的来说,我无法理解fetch()中可读流的意义,因此我需要您的帮助:)。

  • 我正在使用Registfit在我的web服务器中发出一个POST请求。