Kotlin + Spring Webflux File Download - REST API Example
In this section, we will show you how to download files in a RESTful Kotlin + Spring WebFlux application.
More Spring WebFlux practice:
- Kotlin + Spring Webflux File Upload (Single/Multiple)- REST API Example
- Spring Webflux File Upload (Single/Multiple)- REST API Example
- Spring Webflux File Download - REST API Example
- Reactive Rest CRUD APIs using Spring Boot, WebFlux, and Reactive Mongo
Technologies used:
- Kotlin
- Spring Boot 2.5.4
- Spring Webflux
- Java 11
- Gradle
Project Strcuture:
Project Dependency Management(build.gradle.kts)
Spring boot dependencies, no need for an extra library for file upload.
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { id("org.springframework.boot") version "2.5.4" id("io.spring.dependency-management") version "1.0.11.RELEASE" kotlin("jvm") version "1.5.21" kotlin("plugin.spring") version "1.5.21"}
group = "com.knf.dev.demo"version = "0.0.1-SNAPSHOT"java.sourceCompatibility = JavaVersion.VERSION_11
repositories { mavenCentral()}
dependencies { implementation("org.springframework.boot:spring-boot-starter-webflux") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("io.projectreactor:reactor-test")}
tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "11" }}
tasks.withType<Test> { useJUnitPlatform()}
Rest Controller
package com.knf.dev.demo.controller
import org.springframework.web.bind.annotation.RestControllerimport org.springframework.web.bind.annotation.GetMappingimport kotlin.Throwsimport java.io.IOExceptionimport org.springframework.web.bind.annotation.PathVariableimport reactor.core.publisher.Monoimport java.lang.Voidimport org.springframework.http.ZeroCopyHttpOutputMessageimport org.springframework.core.io.ClassPathResourceimport org.springframework.http.HttpHeadersimport org.springframework.http.MediaTypeimport org.springframework.http.server.reactive.ServerHttpResponse
@RestControllerclass DownloadFile {
@GetMapping("/download/{fileName}") @Throws(IOException::class) fun downloadFile( @PathVariable fileName: String, response: ServerHttpResponse ): Mono<Void> { val zeroCopyResponse = response as ZeroCopyHttpOutputMessage response.getHeaders()[HttpHeaders.CONTENT_DISPOSITION] = "attachment; filename=$fileName" response.getHeaders().contentType = MediaType.APPLICATION_OCTET_STREAM val resource = ClassPathResource(fileName) val file = resource.file return zeroCopyResponse.writeWith( file, 0, file.length() ) }}
Spring Boot Main Driver
package com.knf.dev.demoimport org.springframework.boot.autoconfigure.SpringBootApplicationimport org.springframework.boot.runApplication@SpringBootApplicationclass KotlinspringwebfluxdownloadfileApplicationfun main(args: Array<String>) {runApplication<KotlinspringwebfluxdownloadfileApplication>(*args)}
Run the application
Start Spring Boot with the default embedded Tomcat gradle bootRun.
Download File