2016-05-11 29 views
8

La mia applicazione è costruita utilizzando Spring boot (1.3.3.RELEASE) con molla mvc, spring data jpa hibernate. MySql è il database e Jackson è il serializzatore Json. On java 8.Uscita stream JSON in Spring MVC

Voglio restituire un enorme set di dati nel mio metodo di controllo. Invece di recuperare tutti i dati e poi passare nel serializzatore Jackson, voglio restituire un flusso di oggetti come di seguito:

@RequestMapping(value = "/candidates/all", method = RequestMethod.GET) 
public Stream<Candidate> getAllCandidates(){ 
    try { 
     return candidateDao.findAllByCustomQueryAndStream(); 
    } catch(Exception e){ 
     LOG.error("Exception in getCandidates",e); 
    } 
    return null; 
} 

mia DAO è come qui di seguito:

@Query("select c from Candidate c") 
public Stream<Candidate> findAllByCustomQueryAndStream(); 

Tuttavia, Jackson è la serializzazione l'oggetto flusso invece del contenuto del flusso. L'output effettivo riportato di seguito:

{"parallel" : false} 

Come posso chiedere a Jackson di serializzare il contenuto e non l'oggetto dello stream?

risposta

11

Grazie a this sono stato in grado di risolvere il problema.

Avevo fornito un httpMessageConverter personalizzato che comprende come gestire gli stream. In questo modo:

@Bean 
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { 
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); 
ObjectMapper objectMapper =jsonConverter.getObjectMapper(); 
SimpleModule module = new SimpleModule("Stream"); 
module.addSerializer(Stream.class, new JsonSerializer<Stream>() { 


    @Override 
    public void serialize(Stream value, JsonGenerator gen, SerializerProvider serializers) 
      throws IOException, JsonProcessingException { 
     serializers.findValueSerializer(Iterator.class, null) 
     .serialize(value.iterator(), gen, serializers); 

    } 
}); 

objectMapper.registerModule(module); 
jsonConverter.setObjectMapper(objectMapper); 
return jsonConverter; 
} 
+0

per curiosità: come si fa a letto che ' Stream 'usando' RestTemplate'? – Paizo

0

ho scoperto che questo modo di aggiungere il supporto per i flussi rotto la bella uscita di LocalDate/LocalDateTime, ha finito per fare in questo modo:

@Bean 
public Module customModule() { 
    SimpleModule module = new SimpleModule("Stream"); 
    module.addSerializer(Stream.class, new JsonSerializer<Stream>() { 

     @Override 
     public void serialize(Stream value, JsonGenerator gen, SerializerProvider serializers) 
       throws IOException, JsonProcessingException { 
      serializers.findValueSerializer(Iterator.class, null) 
        .serialize(value.iterator(), gen, serializers); 

     } 
    }); 
    return module; 
} 
1

C'è una proposta di soluzione al https://github.com/FasterXML/jackson-modules-java8/issues/3 quale potrebbe essere il modo migliore per andare.

Non incollerò il codice qui, poiché potrebbe essere aggiornato in quel numero.

Finora, ho non trovato alcun problema con quello proposto codice che ho aggiunto in con altri moduli, come il Jdk8Module per facoltativo come

jacksonObjectMapper.registerModule(new StreamModule());