是否有用于Java的事件驱动JSON REST客户端API?

我有一个Java应用程序,它使用Spring的RestTemplate API编写JSON REST服务的简明易读的使用者:

实质上:

restemplate rest=新的restemplate(clienthtprequestfactory);
响应性<项目列表>response=rest.exchange(url,
HttpMethod.GET,
请求实体,
项目列表(类);
对于(项:response.getBody().getItems()){
处理人:非政府组织(项目);
}

JSON响应包含一个项目列表,如您所见,我在自己的代码中有一个事件驱动的设计来依次处理每个项目。但是,整个列表作为响应的一部分存储在内存中,该响应由restemplate.exchange()生成

我希望应用程序能够处理包含大量项的响应(例如50000项),在这种情况下,现有的实现存在两个问题:

  1. 在传输整个HTTP响应之前,不会处理任何一项—这会增加不必要的延迟
  2. 巨大的响应对象位于内存中,在处理完最后一项之前无法进行GC

是否有一个相当成熟的JavaJSON/REST客户端API以事件驱动的方式使用响应

我想它会让你做一些事情,比如:

RestStreamer rest=新的RestStreamer(clientHttpRequestFactory);
//告诉RestStreamer“当解析响应时,遇到JSON
//与JSONPath“$.items[*]”匹配的元素将其传递给“handler”进行处理。
rest.onJsonPath(“$.items[*]”)。句柄(handler);
//告诉RestStreamer发出HTTP请求,将其解析为流。
//我们希望每次解析器遇到一个对象时,“handler”都会被传递一个对象
//一项。
execute(url、HttpMethod.GET、requestEntity);

我很感激我可以使用Jackson、GSON等公司的流式JSON API来实现这种行为——但我希望有人告诉我,有一些东西可以通过与HTTP方面集成的简洁、富有表现力的API来可靠地实现这一点

几个月后,回来回答我自己的问题

我没有找到一个可表达的API来做我想做的事情,但是我能够通过将HTTP主体作为流获取,并使用JacksonJsonParser来实现所需的行为:

ClientHttpRequest请求=
createRequest(uri,HttpMethod.GET);
ClientHttpResponse response=request.execute();
返回handleJsonStream(response.getBody(),handler);

…handleJsonStream设计用于处理JSON,如下所示:

{项目:[
{字段:值;..},
{字段:值,…},
……还有几千。。。
] }

…它验证指向数组开头的标记;每次遇到数组元素时,它都会创建一个对象,并将其提供给处理程序

//JsonFactory必须来自ObjectMapper,否则就不会是
//能够执行readValueAs()
静态JsonFactory JsonFactory=newObjectMapper().getFactory();
公共静态int-handleJsonStream(InputStream,ItemHandler)引发IOException{
JsonParser parser=jsonFactory.createJsonParser(流);
验证(parser.nextToken(),START\u对象,parser);
验证(parser.nextToken(),字段名称,parser);
验证(parser.getCurrentName(),“items”,解析器);
验证(parser.nextToken(),START\u数组,parser);
整数计数=0;
while(parser.nextToken()!=END\u数组){
验证(parser.getCurrentToken(),START\u对象,解析器);
Item=parser.readValueAs(Item.class);
处理人:非政府组织(项目);
计数++;
}
parser.close();//希望可以忽略剩余的结束标记。
返回计数;
}

verify()只是一个私有静态方法,如果前两个参数不相等,它会引发异常

这个方法的关键是,不管流中有多少项,这个方法都只引用一个项

发表评论