Java Spring MVC中的JSON流输出
我的应用程序是使用SpringBoot(1.3.3.RELEASE)和SpringMVC、SpringData JPA Hibernate构建的。MySql是数据库,Jackson是JSON序列化程序。在Java8上 我想在我的控制器方法中返回一个巨大的数据集。我不想检索所有数据,然后将其传递到Jackson序列化程序,而是希望返回如下所示的对象流:Java Spring MVC中的JSON流输出,java,rest,spring-mvc,jackson,java-stream,Java,Rest,Spring Mvc,Jackson,Java Stream,我的应用程序是使用SpringBoot(1.3.3.RELEASE)和SpringMVC、SpringData JPA Hibernate构建的。MySql是数据库,Jackson是JSON序列化程序。在Java8上 我想在我的控制器方法中返回一个巨大的数据集。我不想检索所有数据,然后将其传递到Jackson序列化程序,而是希望返回如下所示的对象流: @RequestMapping(value = "/candidates/all", method = RequestMeth
@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;
}
@Query("select c from Candidate c")
public Stream<Candidate> findAllByCustomQueryAndStream();
如何指示Jackson序列化内容而不是流对象?多亏了我能够解决这个问题
我提供了一个定制的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;
}
@Bean
公共映射Jackson2HttpMessageConverter映射Jackson2HttpMessageConverter(){
MappingJackson2HttpMessageConverter jsonConverter=新的MappingJackson2HttpMessageConverter();
ObjectMapper ObjectMapper=jsonConverter.getObjectMapper();
SimpleModule=新的SimpleModule(“流”);
module.addSerializer(Stream.class,
新的JsonSerializer(){
@凌驾
公共void序列化(流值、JsonGenerator gen、SerializerProvider序列化器)
抛出IOException、JsonProcessingException{
serializers.findValueSerializer(Iterator.class,null)
.serialize(value.iterator(),gen,serializers);
}
});
objectMapper.registerModule(模块);
setObjectMapper(objectMapper);
返回jsonConverter;
}
我发现,这种添加流支持的方式打破了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;
}
@Bean
公共模块customModule(){
SimpleModule=新的SimpleModule(“流”);
addSerializer(Stream.class,新的JsonSerializer()){
@凌驾
公共void序列化(流值、JsonGenerator gen、SerializerProvider序列化器)
抛出IOException、JsonProcessingException{
serializers.findValueSerializer(Iterator.class,null)
.serialize(value.iterator(),gen,serializers);
}
});
返回模块;
}
有一个建议的解决方案,可能是更好的方法
我不会将代码粘贴到这里,因为它可能会在该期中得到更新
到目前为止,我还没有发现我与其他模块(如可选as的Jdk8Module)一起添加的建议代码有任何问题
jacksonObjectMapper.registerModule(new StreamModule());
从控制器返回Iterable
流通过Iterable Iterable=Stream::iterator转换为迭代器代码>
@RequestMapping(value = "/candidates/all", method = RequestMethod.GET)
public Iterable<Candidate> getAllCandidates(){
...
return candidateDao.findAllByCustomQueryAndStream()::iterator;
@RequestMapping(value=“/candidates/all”,method=RequestMethod.GET)
公共Iterable getAllCandidates(){
...
返回候选dao.findAllByCustomQueryAndStream()::迭代器;
出于好奇:您如何使用restemplate
阅读Stream
?Stream.iterator是一种终端操作。这意味着它将所有内容缓存在ram中。这与使用Iterable作为getAllCandidates OutputOutput没有区别,目前正在研究如何减少大型数据集和spring mvc的内存占用你怎么说它会把所有东西都缓存在内存中?这是没有意义的吗?
@RequestMapping(value = "/candidates/all", method = RequestMethod.GET)
public Iterable<Candidate> getAllCandidates(){
...
return candidateDao.findAllByCustomQueryAndStream()::iterator;