Enviando um stream de documentos para um ponto final de Jersey @POST

Eu quero ser capaz de enviar um stream de um monte de documentos para um serviço da web. Isso economizará na sobrecarga de solicitação / resposta HTTP e se concentrará nos próprios documentos.

Em python você pode fazer algo assim:

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) 

Estou procurando um exemplo de alguém transmitindo uma solicitação para uma API de descanso de Jersey. Eu estava esperando para ver o lado do cliente e do lado do servidor para mostrar o trabalho. Mas eu estou lutando duro para encontrar um exemplo lá fora.

O exemplo Idealmente mostraria:

 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 

Se acertarmos, você estará processando entidades no Servidor enquanto ainda as envia no Cliente! Grande vitória!

Uma das maneiras mais simples de conseguir isso é deixar Jersey fornecer ao manipulador POST um InputStream para o corpo HTTP POST. O método pode usar o analisador InputStream e JSON de sua escolha para analisar e manipular cada object.

No exemplo a seguir, o Jackson ObjectReader produz um MappingIterator que analisa e processa cada documento da Person na matriz à medida que é entregue ao servidor.

 /** * 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); } } } 

Da mesma forma, a estrutura do cliente Jersey pode enviar um stream de documentos quando configurado com um Jackson ObjectMapper . O exemplo a seguir demonstra isso com a estrutura de teste de Jersey. O cliente transmite um iterador arbitrariamente grande de documentos da 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); } } 
    Intereting Posts