将文档流发送到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); } }