I recently come across the situation where I need to Integrate an API that requires uploading the File. The content of the File is the Request Information for the API.
Sometimes you need to call an API that expects you to upload a file, where the content of the file itself is the request data. This guide shows you a simple and clean way to:
Create a file dynamically from your DTO data
Upload that file using Spring WebFlux’s WebClient
Understand why certain Spring abstractions are used
- Create File Content from DTO & Write to Disk Assume you have a DTO representing customer data for the transfer.
data class TransferRecord(
val custname: String,
val amount: String
)
You need to convert this DTO into a formatted file content (e.g., pipe-separated values), then write that content to a file.
fun createContentAndWriteToFile(
record: TransferRecord,
filePath: String
): File {
val firstLine = "${record.custname}|C|000000|${record.amount}|0000"
val secondLine = "00000000000|D|000000|${record.amount}|0000"
val content = """
$firstLine
$secondLine
""".trimIndent()
val file = File(filePath)
file.writeText(content)
return file
}
Explanation:
We build the file content string based on your business logic.
Then, write the content to the specified file path and return the File object.
suspend fun postUploadFile(
file: File,
url: String,
): String {
val resource = FileSystemResource(file)
val multipartBody = MultipartBodyBuilder().apply {
part("transferFile", resource)
}.build()
val responseAsString =
webClient.post()
.uri(url)
.body(BodyInserters.fromMultipartData(multipartBody))
.awaitExchange { clientResponse ->
processResponse(clientResponse)
}
${objectMapper.writeValueAsString(responseAsString)}")
return responseAsString.toString()
}
Why Use FileSystemResource?
java.io.File is just a pointer to a file path — it doesn't provide streaming or metadata capabilities.
Spring's Resource abstraction (e.g., FileSystemResource) wraps the file and supports streaming, metadata, and HTTP headers needed for multipart file uploads.
.
Multipart Form Data
HTTP multipart/form-data is used for uploading files and large form data.
The request body is split into multiple parts, each with headers and content.
In this example, the part name is "transferFile" matching what the receiving API expects.
- Controller Side (Handling Multipart File Upload) When you create the receiving endpoint, use @RequestPart to bind the file part:
@PostMapping("/upload")
suspend fun uploadFile(@RequestPart("transferFile") file: FilePart): string{
// Process the file content
val content = file.content().map { buffer ->
buffer.toString(StandardCharsets.UTF_8)
}.reduce { acc, next -> acc + next }
// Your business logic with file content
return ResponseEntity.ok("File uploaded successfully").toString()
}
Top comments (0)