Closed nardost closed 3 years ago
This bug took me hours to understand. Apparently, files larger than 256K are split into a Flux of 1K sized DataBuffer chunks. I was saving only the first element of the flux thinking that was the entire file. This worked for files smaller than 256K. But for files larger than 256K, the first element was a mere 1K sized DataBuffer, which showed as a blank image when retrieved. Here is the buggy code:
public Mono<ServerResponse> saveImage(ServerRequest request) {
final Mono<DataBuffer> dataBuffer = request.body(BodyExtractors.toParts())
.filter(part -> part.name().equals(FILE_FIELD_NAME))
.cast(FilePart.class)
.flatMap(FilePart::content).elementAt(0);
return dataBuffer.flatMap(buffer -> {
final byte[] bytes = new byte[buffer.readableByteCount()];
DataBufferUtils.release(buffer.read(bytes));
final Photo photo = new Photo(
UUID.randomUUID().toString(),
"image/jpeg", //TODO: Get this from the image file itself
new Binary(BsonBinarySubType.BINARY, bytes),
getMD5Hash(bytes),
new Date());
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(photoService.savePhoto(photo).map(Hash::new), Hash.class);
});
}
The solution was to collect the flux of 1K sized DataBuffer into a single DataBuffer with ```DataBufferUtils::join``` as follows:
public Mono<ServerResponse> saveImage(ServerRequest request) {
final Mono<DataBuffer> dataBuffer = DataBufferUtils.join(request.body(BodyExtractors.toParts())
.filter(part -> part.name().equals(FILE_FIELD_NAME))
.cast(FilePart.class)
.flatMap(FilePart::content));
return dataBuffer.flatMap(buffer -> {
final byte[] bytes = new byte[buffer.readableByteCount()];
DataBufferUtils.release(buffer.read(bytes));
final Photo photo = new Photo(
UUID.randomUUID().toString(),
"image/jpeg",
new Binary(BsonBinarySubType.BINARY, bytes),
getMD5Hash(bytes),
new Date());
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(photoService.savePhoto(photo).map(Hash::new), Hash.class);
});
}
Investigate why some images (apparently those with size greater than 256k) are blank when they are saved and retrieved.