将文档流发送到Jersey @POST端点

我希望能够一堆文档流发送到Web服务。 这将节省Http请求/响应开销并专注于文档本身。

在python中你可以这样做:

r = requests.post('https://stream.twitter.com/1/statuses/filter.json', data={'track': 'requests'}, auth=('username', 'password'), stream=True) for line in r.iter_lines(): if line: # filter out keep-alive new lines print json.loads(line) 

我正在寻找有人将请求流式传输到泽西岛restapi的示例。 我希望看到客户端和服务器端显示它正常工作。 但我很难找到一个例子。

理想情况下,该示例将显示:

 Client: Open request Iterate over huge document list Write document to open request stream Close request Server: @POST method Open entity stream Iterate over entity stream while next document is available Process document Close entity stream 

如果我们做对了,您将在服务器上处理实体,同时仍然在客户端上发送它们! 巨大的胜利!

实现此目的的最简单方法之一是让Jersey为POST POST处理程序提供一个用于HTTP POST主体的InputStream 。 该方法可以使用您选择的InputStream和JSON解析器来解析然后处理每个对象。

在下面的示例中,一个Jackson ObjectReader生成一个MappingIterator ,它在将数据传递到服务器时解析并处理数组中的每个Person文档。

 /** * Parse and process an arbitrarily large JSON array of Person documents */ @Path("persons") public static class PersonResource { private static final ObjectReader reader = new ObjectMapper().readerFor(Person.class); @Path("inputstream") @Consumes("application/json") @POST public void inputstream(final InputStream is) throws IOException { final MappingIterator persons = reader.readValues(is); while (persons.hasNext()) { final Person person = persons.next(); // process System.out.println(person); } } } 

同样,Jersey客户端框架可以在配置Jackson ObjectMapper时发送文档流。 以下示例使用Jersey Test框架演示了这一点。 客户端流式传输Person文档的任意大迭代器

 public class JacksonStreamingTest extends JerseyTest { @Override protected Application configure() { return new ResourceConfig(PersonResource.class, ObjectMapperProvider.class); } /** * Registers the application {@link ObjectMapper} as the JAX-RS provider for application/json */ @Provider @Produces(MediaType.APPLICATION_JSON) public static class ObjectMapperProvider implements ContextResolver { private static final ObjectMapper mapper = new ObjectMapper(); public ObjectMapper getContext(final Class objectType) { return mapper; } } @Override protected void configureClient(final ClientConfig config) { config.register(ObjectMapperProvider.class); } @Test public void test() { final Set persons = Collections.singleton(Person.of("Tracy", "Jordan")); final Response response = target("persons/inputstream").request().post(Entity.json(persons.iterator())); assertThat(response.getStatus()).isEqualTo(204); } }