2016-05-11 5 views
8

Мое приложение построено с использованием пружинного ботинка (1.3.3.RELEASE) с пружинным mvc, пружинными данными jpa hibernate. MySql - это база данных, а Jackson - сериализатор Json. На java 8.Потоковый вывод JSON весной MVC

Я хочу вернуть огромный набор данных в мой метод контроллера. Вместо извлечения всех данных, а затем переходит в сериализатор Джексона, я хочу, чтобы вернуть поток объектов, как показано ниже:

@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; 
} 

моего DAO, как показано ниже:

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

Однако Джексон сериализации объект потока, а не содержимое потока. Фактический результат ниже:

{"parallel" : false} 

Как я могу обучить Джексона сериализации содержимого, а не объекта потока?

ответ

11

Благодаря this Мне удалось решить проблему.

У меня был пользовательский httpMessageConverter, который понимает, как обрабатывать потоки. Как так:

@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

из любопытства: как ты читаешь, что ' Поток 'using' RestTemplate'? – Paizo

0

Я обнаружил, что этот способ добавления поддержки потоков сломал хороший выход LocalDate/LocalDateTime, в конечном итоге делает это так:

@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

Существует предложенное решение в https://github.com/FasterXML/jackson-modules-java8/issues/3 что может быть лучшим способом.

Я не буду вставлять код здесь, так как он может быть обновлен в этой проблеме.

До сих пор я не нашел никаких проблем с этим предложенным кодом, который я добавил в с другими модулями, такими как Jdk8Module для необязателена

jacksonObjectMapper.registerModule(new StreamModule());