Issue
I have a stream of data from database using Spring Data Jpa that needs to be Json serialized and write to a Http response, without storing in memory. This is the sample code.
try (Stream<Employee> dataStream = empRepo.findAllStream()) {
response.setHeader("content-type", "application/json");
PrintWriter respWriter = response.getWriter();
respWriter.write("["); // array begin
dataStream.forEach(data -> {
try {
respWriter.write(jsonSerialize(data));
respWriter.write(",");
} catch (JsonProcessingException e) {
log(e);
}
entityManager.detach(data);
});
respWriter.write("]"); // array end
respWriter.flush();
} catch (IOException e) {
log(e);
}
}
But this logic will write an extra comma after the last element. How can I not to do respWriter.write(",");
, if it is the last element?
There are solutions with stream operators - peek
, reduce
etc, but what's the most optimized solution? Is there something like Stream.hasNext()
so that I can use an if
condition inside forEach
?
Solution
First I'd like to say that I don't think that your problem is a good fit for a single pipeline stream. You are performing side effects both with the write
call and the detach
call. Maybe you are better of with a normal for-loop? Or using multiple streams instead?
That being said, you can use the technique that Holger describes in an answer to this question: Interleave elements in a stream with separator
try (Stream<Employee> dataStream = empRepo.findAllStream()) {
response.setHeader("content-type", "application/json");
PrintWriter respWriter = response.getWriter();
respWriter.write("["); // array begin
dataStream.map(data -> {
try {
String json = jsonSerialize(data);
// NOTE! It is confusing to have side effects like this in a stream!
entityManager.detach(data);
return json;
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
})
.flatMap(json -> Stream.of(",", json))
.skip(1)
.forEach(respWriter::write);
respWriter.write("]"); // array end
respWriter.flush();
} catch (IOException e) {
log(e);
}
Answered By - Lii
Answer Checked By - Gilberto Lyons (JavaFixing Admin)