Spring WebFlux - Content type 'application/xml' not supported for bodyType=org.springframework.web.multipart.MultipartFile
Asked Answered
F

1

5

I am using spring-webflux and want to upload files .... everything works great with just spring-web but when it comes to webflux i have not a clue what's wrong .

Be careful in the difference ... i am using :

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

So let's say we have the below @RestController , for Spring Web it works like charm:

@PostMapping(value = "/uploadFile")
public Response uploadFile(@RequestParam("file") MultipartFile file) {

}

Now trying the same with Spring-webflux produces the below error :

{
    "timestamp": "2019-04-11T13:31:01.705+0000",
    "path": "/upload",
    "status": 400,
    "error": "Bad Request",
    "message": "Required MultipartFile parameter 'file' is not present"
}

I found from a random stackoverflow question that i have to use @RequestPart instead of @RequestParam but now i am getting the below error and i don't have a clue why this happens ?

The error is the below :

{
    "timestamp": "2019-04-11T12:27:59.687+0000",
    "path": "/uploadFile",
    "status": 415,
    "error": "Unsupported Media Type",
    "message": "Content type 'application/xml' not supported for bodyType=org.springframework.web.multipart.MultipartFile"
}

Even with .txt files is producing the same error :

{
    "timestamp": "2019-04-11T12:27:59.687+0000",
    "path": "/uploadFile",
    "status": 415,
    "error": "Unsupported Media Type",
    "message": "Content type 'application/xml' not supported for bodyType=org.springframework.web.multipart.MultipartFile"
}

Below is the Postman Configuration which is pretty straight forward , i am just calling with a post request and modified only the body as shown in the picture .

enter image description here

By the way i have added the needed properties on application.properties too :)

## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB
Foliole answered 11/4, 2019 at 12:33 Comment(10)
Possible duplicate of What is http multipart request?Theater
Well if you look a at the answer you will see that the content-type for a multipart can't be application/xml. So there is that.Theater
@Theater I get the same error for text/plain or whatever file i add sir :)Foliole
I think there is a problem with your request cause I created a sample project gist.github.com/Julien-Eyraud/4a9384e11372004d0218a9e8a961108a and it just workTheater
@Theater I followed this tutorial :) callicoder.com/… but he is using spring-web we are using spring-webflux and there is all the problem . I used the same request for spring-web and it works :'( i am troubleshouting with it all day :(Foliole
@Theater can you show me how you called it from postman or something :) ? I will be very happy to accept your answer .Foliole
@Theater using your service with a .txt file i get the below : Content type 'text/plain' not supported for bodyType=org.springframework.web.multipart.MultipartFileFoliole
ibb.co/q9KppgY don't know if it's helping. But I can see that you set a header. I didn'tTheater
Completely modified the question with new image so you can see what exactly happens . Please see that i am using spring-webfluxFoliole
@Theater Somebody posted an amazing answer .... as you can see it was complicated :)Foliole
B
6

As documentation sais :

The DefaultServerWebExchange uses the configured HttpMessageReader<MultiValueMap<String, Part>> to parse multipart/form-data content into a MultiValueMap.

To parse multipart data in streaming fashion, you can use the Flux returned from an HttpMessageReader instead.

With few words you need to do something like this:

    @RequestMapping(path = "/uploadFile", method = RequestMethod.POST, 
        consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Flux<String> uploadFile(@RequestBody Flux<Part> parts) {
    //...
    }

Look at this example

Blagoveshchensk answered 11/4, 2019 at 13:32 Comment(5)
Thank you Nikolay , i am very new to this ... how i can get the file from inside the parts :) ?Foliole
Look at this exampleBlagoveshchensk
You already learned that switching from web to webflux is more than changeing the artifactId ;)Blagoveshchensk
Nikolay i have a question ? Will this work okay for 1 GB files or the Service will crash ?Foliole
Webflux works great for uploading/downloading large files. There were some issues for streaming very large files few months ago but I think it is fixed now. It all depends on how is used.Blagoveshchensk

© 2022 - 2024 — McMap. All rights reserved.