Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Curl post multipart file to spring boot rest endpoint

I am trying to post a file to a restful endpoint implemented in spring boot using Curl and it throws the following error:

    $ curl -v http://localhost:8081/qas/uploadCsv -X POST -F "[email protected]"
Note: Unnecessary use of -X or --request, POST is already inferred.
* timeout on name lookup is not supported
*   Trying ::1...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to localhost (::1) port 8081 (#0)
> POST /qas/uploadCsv HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.46.0
> Accept: */*
> Content-Length: 4257762
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------e16823418f4c8f54
>
< HTTP/1.1 100 Continue
} [155 bytes data]
< HTTP/1.1 400 Bad Request
< Server: Apache-Coyote/1.1
< X-Application-Context: application:8081
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Mon, 11 Apr 2016 14:27:42 GMT
< Connection: close
<
{ [247 bytes data]
100 4158k    0   236  100 4157k   1888  32.4M --:--:-- --:--:-- --:--:-- 32.4M{"timestamp":1460384862046,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.MissingServletRequestParameterException","message":"Required MultipartFile parameter 'file' is not present","path":"/qas/uploadCsv"}
* Closing connection 0

I must be missing something basic but cannot see what it is. It is looking for the request param 'file' and am not sure how to send this through Curl.

Spring java config has following beans:

@Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxFileSize("1000MB");
        factory.setMaxRequestSize("1000MB");
        return factory.createMultipartConfig();
    }

    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSizePerFile(10000000);
        return multipartResolver;
    }

My spring boot web service is as follows:

@RequestMapping(value = "/uploadCsv", method = RequestMethod.POST, consumes = {"multipart/*"})
public @ResponseBody result handleFileUpload(@RequestParam("file") MultipartFile file) {

in the above signature it is looking for the requestParam file which correlates with the cUrl error.

    "status":400,"error":"Bad Request",
"exception":"org.springframework.web.bind.MissingServletRequestParameterException",
"message":"Required MultipartFile parameter 'file' is not present","path":"/qas/uploadCsv"}

This request works in postman which submits the following request:

POST /qas/uploadCsv HTTP/1.1
Host: localhost:8081
Cache-Control: no-cache
Postman-Token: d62a469b-16c8-b30a-4168-7622d9695c57
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename=""
Content-Type: 


----WebKitFormBoundary7MA4YWxkTrZu0gW

I also have a mockMvc integration test that works fine. Comparing the two (cUrl vs postman) in the cUrl there is no content disposition which contains the file param. Have looked around on google and cannot see to send this request? Any pointers

Thanks in advance

UPDATE:

I tried the solution in the following link

File upload working under Jetty but not under Tomcat

Using the same cURL command above the file is null throwing the error below

$ curl -v http://localhost:8081/qas/uploadCsv -X POST -F "[email protected]" -H "Content-Type: multipart/form-data"
Note: Unnecessary use of -X or --request, POST is already inferred.
* timeout on name lookup is not supported
*   Trying ::1...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to localhost (::1) port 8081 (#0)
> POST /qas/uploadCsv HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.46.0
> Accept: */*
> Content-Length: 4257762
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------e6cd31736e52dfa2
>
< HTTP/1.1 100 Continue
} [155 bytes data]
100 4157k    0     0  100 4157k      0   681k  0:00:06  0:00:06 --:--:--     0< HTTP/1.1 500 Internal Server Error
< Server: Apache-Coyote/1.1
< X-Application-Context: application:8081
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 12 Apr 2016 07:23:18 GMT
< Connection: close
<
100 4157k    0     0  100 4157k      0   622k  0:00:06  0:00:06 --:--:--     0{ [4 bytes data]
100 4158k    0   174  100 4157k     26   622k  0:00:06  0:00:06 --:--:--     0{"timestamp":1460445797961,"status":500,"error":"Internal Server Error","exception":"java.lang.NullPointerException","message":"No message available","path":"/qas/uploadCsv"}
* Closing connection 0
like image 326
user1107753 Avatar asked Apr 11 '16 14:04

user1107753


2 Answers

I think this is due to the fact that file here is not a parameter. According to Spring web, a parameter is a 'query' parameter, so for example /api?foo=bar, foo is here the parameter in this request.

So in your case, Spring complains about a missing parameter file because it expects the request to look like http://localhost:8081/qas/uploadCsv?file=something.

Changing the method signature from

handleFileUpload(@RequestParam("file") MultipartFile file)

to

handleFileUpload(@RequestPart("file") MultipartFile file)

should fix your issue

like image 66
Ahmed Sayed Avatar answered Oct 19 '22 19:10

Ahmed Sayed


Curl POST + Multipart To POST with a file, add this -F file=@"path/to/data.txt"

curl -F file=@"test.csv" http://localhost:8081/qas/uploadCsv
like image 1
Bhushan Uniyal Avatar answered Oct 19 '22 19:10

Bhushan Uniyal