5

I have controller method that receives and uploaded file from a web form. How can I extract the byte array out of the FilePart and save it to DB?

I can do it by saving the FilePart to a file using FilePart.transferTo() but that seems slow and ugly. Any nicer way of doing it?

import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.bind.annotation.*;


 Mono<UploadResult> uploadFile(@RequestParam("files") FilePart file){

    byte[] fileAsByteArray = convertFilePartToByteArray(file);

    fileService.saveByteArrayToDB(fileAsByteArray);

    /* Rest of the method */
 }
Vahid
  • 190
  • 3
  • 9

3 Answers3

3

You could utilize the internal dataBuffer and convert them to byte[].

The helper function:

suspend fun FilePart.toBytes(): ByteArray {
    val bytesList: List<ByteArray> = this.content()
            .flatMap { dataBuffer -> Flux.just(dataBuffer.asByteBuffer().array()) }
            .collectList()
            .awaitFirst()

    // concat ByteArrays
    val byteStream = ByteArrayOutputStream()
    bytesList.forEach { bytes -> byteStream.write(bytes) }
    return byteStream.toByteArray()
}

The controller:

@PostMapping("/upload", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
suspend fun upload(@RequestPart("file") file: Mono<FilePart>) {
    val bytes = file.awaitFirst().toBytes()
    myService.handle(bytes) // do your business stuff
}
Tien Do Nam
  • 3,630
  • 3
  • 15
  • 30
0

Do you mean the interface org.springframework.http.codec.multipart.FilePart?

See How to correctly read Flux<DataBuffer> and convert it to a single inputStream

ggb667
  • 1,881
  • 2
  • 20
  • 44
  • Fair enough, I added some imports to make the context more clear. Anyway you read my mind correctly :) but file.content().asByteBuffer() wouldn't work as file is of type Flux – Vahid Feb 25 '20 at 15:36
-1

You can do something like this:

file.content()
.map { it -> it.asInputStream().readAllBytes() }
.map { it -> fileService.saveByteArrayToDB(it) } // it is Byte array