is the data type used to represent a chunk of data received in a multipart request. There are methods on the PartData interface to convert the data to a , , or a ByteBuffer.

    Route arguments of type will be treated as only intended to receive a single file and each chunk of the received file will be sent downstream. If the generic type is something other than PartData, conversion will be attempted using Micronaut’s conversion service. Conversions to String and byte[] are supported by default.

    If requirements dictate you must have knowledge about the metadata of the file being received, a special class called has been created that is a Publisher<PartData>, but also has file information like the content type and file name.

    Streaming file upload

    1. import io.micronaut.http.HttpResponse
    2. import io.micronaut.http.HttpStatus
    3. import io.micronaut.http.MediaType
    4. import io.micronaut.http.annotation.Controller
    5. import io.micronaut.http.annotation.Post
    6. import io.micronaut.http.multipart.StreamingFileUpload
    7. import io.reactivex.Single
    8. import org.reactivestreams.Publisher
    9. @Controller("/upload")
    10. class UploadController {
    11. @Post(value = "/", consumes = MediaType.MULTIPART_FORM_DATA, produces = MediaType.TEXT_PLAIN) (1)
    12. Single<HttpResponse<String>> upload(StreamingFileUpload file) { (2)
    13. File tempFile = File.createTempFile(file.filename, "temp")
    14. Publisher<Boolean> uploadPublisher = file.transferTo(tempFile) (3)
    15. Single.fromPublisher(uploadPublisher) (4)
    16. .map({ success ->
    17. if (success) {
    18. HttpResponse.ok("Uploaded")
    19. } else {
    20. HttpResponse.<String>status(HttpStatus.CONFLICT)
    21. .body("Upload Failed")
    22. }
    23. })
    24. }
    25. }

    Streaming file upload

    1. import io.micronaut.http.HttpResponse
    2. import io.micronaut.http.HttpStatus
    3. import io.micronaut.http.MediaType
    4. import io.micronaut.http.annotation.Controller
    5. import io.micronaut.http.annotation.Post
    6. import io.micronaut.http.multipart.StreamingFileUpload
    7. import io.reactivex.Single
    8. import java.io.File
    9. @Controller("/upload")
    10. class UploadController {
    11. @Post(value = "/", consumes = [MediaType.MULTIPART_FORM_DATA], produces = [MediaType.TEXT_PLAIN]) (1)
    12. fun upload(file: StreamingFileUpload): Single<HttpResponse<String>> { (2)
    13. val tempFile = File.createTempFile(file.filename, "temp")
    14. val uploadPublisher = file.transferTo(tempFile) (3)
    15. return Single.fromPublisher(uploadPublisher) (4)
    16. .map { success ->
    17. if (success) {
    18. HttpResponse.ok("Uploaded")
    19. } else {
    20. HttpResponse.status<String>(HttpStatus.CONFLICT)
    21. .body("Upload Failed")
    22. }
    23. }
    24. }
    25. }

    Whole Data Types

    Route arguments that are not publishers will cause the route execution to be delayed until the upload has finished. The received data will attempt to be converted to the requested type. Conversions to a String or byte[] are supported by default. In addition, the file can be converted to a POJO if a media type codec has been registered that supports the media type of the file. A media type codec is included by default that allows conversion of JSON files to POJOs.

    Receiving a byte array

    Receiving a byte array

    1. import io.micronaut.http.HttpResponse
    2. import io.micronaut.http.MediaType
    3. import io.micronaut.http.annotation.Controller
    4. import io.micronaut.http.annotation.Post
    5. import java.nio.file.Files
    6. import java.nio.file.Path
    7. import java.nio.file.Paths
    8. @Controller("/upload")
    9. class BytesUploadController {
    10. @Post(value = "/bytes",
    11. consumes = MediaType.MULTIPART_FORM_DATA,
    12. produces = MediaType.TEXT_PLAIN) (1)
    13. HttpResponse<String> uploadBytes(byte[] file, String fileName) { (2)
    14. try {
    15. File tempFile = File.createTempFile(fileName, "temp")
    16. Path path = Paths.get(tempFile.absolutePath)
    17. Files.write(path, file) (3)
    18. HttpResponse.ok("Uploaded")
    19. } catch (IOException exception) {
    20. HttpResponse.badRequest("Upload Failed")
    21. }
    22. }
    23. }
    1. import io.micronaut.http.HttpResponse
    2. import io.micronaut.http.MediaType
    3. import io.micronaut.http.annotation.Controller
    4. import io.micronaut.http.annotation.Post
    5. import java.io.File
    6. import java.io.IOException
    7. import java.nio.file.Files
    8. import java.nio.file.Path
    9. import java.nio.file.Paths
    10. @Controller("/upload")
    11. class BytesUploadController {
    12. @Post(value = "/bytes",
    13. consumes = [MediaType.MULTIPART_FORM_DATA],
    14. produces = [MediaType.TEXT_PLAIN]) (1)
    15. fun uploadBytes(file: ByteArray, fileName: String): HttpResponse<String> { (2)
    16. return try {
    17. val tempFile = File.createTempFile(fileName, "temp")
    18. val path = Paths.get(tempFile.absolutePath)
    19. Files.write(path, file) (3)
    20. HttpResponse.ok("Uploaded")
    21. } catch (exception: IOException) {
    22. HttpResponse.badRequest("Upload Failed")
    23. }
    24. }
    25. }

    If requirements dictate you must have knowledge about the metadata of the file being received, a special class called CompletedFileUpload has been created that has methods to retrieve the data of the file, but also has file information like the content type and file name.

    File upload with metadata

    File upload with metadata

    1. import io.micronaut.http.MediaType
    2. import io.micronaut.http.annotation.Controller
    3. import io.micronaut.http.annotation.Post
    4. import io.micronaut.http.multipart.CompletedFileUpload
    5. import java.nio.file.Files
    6. import java.nio.file.Path
    7. import java.nio.file.Paths
    8. @Controller("/upload")
    9. class CompletedUploadController {
    10. @Post(value = "/completed",
    11. consumes = MediaType.MULTIPART_FORM_DATA,
    12. produces = MediaType.TEXT_PLAIN) (1)
    13. HttpResponse<String> uploadCompleted(CompletedFileUpload file) { (2)
    14. try {
    15. File tempFile = File.createTempFile(file.filename, "temp") (3)
    16. Path path = Paths.get(tempFile.absolutePath)
    17. Files.write(path, file.bytes) (3)
    18. HttpResponse.ok("Uploaded")
    19. } catch (IOException exception) {
    20. HttpResponse.badRequest("Upload Failed")
    21. }
    22. }
    23. }

    File upload with metadata

    1. import io.micronaut.http.HttpResponse
    2. import io.micronaut.http.MediaType
    3. import io.micronaut.http.annotation.Controller
    4. import io.micronaut.http.annotation.Post
    5. import io.micronaut.http.multipart.CompletedFileUpload
    6. import java.io.File
    7. import java.io.IOException
    8. import java.nio.file.Files
    9. import java.nio.file.Path
    10. import java.nio.file.Paths
    11. @Controller("/upload")
    12. class CompletedUploadController {
    13. @Post(value = "/completed",
    14. consumes = [MediaType.MULTIPART_FORM_DATA],
    15. produces = [MediaType.TEXT_PLAIN]) (1)
    16. fun uploadCompleted(file: CompletedFileUpload): HttpResponse<String> { (2)
    17. return try {
    18. val tempFile = File.createTempFile(file.filename, "temp") (3)
    19. val path = Paths.get(tempFile.absolutePath)
    20. Files.write(path, file.bytes) (3)
    21. HttpResponse.ok("Uploaded")
    22. } catch (exception: IOException) {
    23. HttpResponse.badRequest("Upload Failed")
    24. }
    25. }
    26. }