5

I want to pass json and file together in the controller using curl. I have following method in controller.

@PostMapping(value = /api/campaign, headers = {"content-type=multipart/mixed","content-type=multipart/form-data"})
    @ResponseBody
    @ResponseStatus(HttpStatus.CREATED)
    public @Valid ResponseDTO campaignCreator (@Valid @RequestBody CampaignCreatorDTO campaignCreatorDTO, @RequestPart("file") MultipartFile adGraphic){
}

Below is the curl command

curl -i -X POST -H "Content-Type: multipart/mixed" -d "campaignCreatorDTO={\"edipi\":123456789,\"firstName\":\"John\",\"lastName\":\"Smith\",\"email\":\"john.smith@gmail.com\"};type=application/json" -F "file=@newfile.png;type=image/png"  http://localhost:8080/api/campaign

controller method is not getting called. when I put json in a file and use file in curl command in place of direct json it works. But I do not want to use file for json.

I tried to use @RequestPart for json object but same issue.

is there any way to pass multipart file inside json I mean CampaignCreatorDTO object?

Update:: Now I am able to pass RequestPart for both type but image size is coming 0 bytes. Though iamge is present in the filesystem.

Updated Code :: now using below code, and getting filesize as 0 bytes.

@PostMapping(value = /api/campaign, consumes = {"multipart/form-data","multipart/mixed"})
    @ResponseBody
    @ResponseStatus(HttpStatus.CREATED)
    public @Valid ResponseDTO campaignCreator (@Valid @RequestPart("json") CampaignCreatorDTO campaignCreatorDTO, @RequestPart("file") MultipartFile adGraphic) {
}

I tried solution given in this link but still same issue

Spring MVC Multipart Request with JSON

this is how client is paasing the data to server

let formData = new FormData()

const blob = new Blob([json], {
type: 'application/json'
});

formData.append("json", blob)
formData.append("file", values.adCreativeImageCover)

let authToken = sessionStorage.getItem("authToken")

fetch(/api/campaign, {
method: "POST",
headers: {
'Accept': 'application/json',
'X-Auth-Token': authToken,
},
mode: 'cors',
body: formData
})
Anjali
  • 1,623
  • 5
  • 30
  • 50
  • You request can't be `multipart/form-data` and `application/json` at the same time. You can either do it with two requests or send the json with request parameters – gherkin Oct 26 '18 at 09:14
  • you just need to encode either your json (to a URL compatible format, e.g. URL encode) or your file(to something like base64 string) and decode it on server – gherkin Oct 26 '18 at 10:14
  • Possible duplicate of https://stackoverflow.com/questions/21329426/spring-mvc-multipart-request-with-json – Sumesh TG Oct 30 '18 at 13:38
  • @SumeshTG Doing same, but still getting file size as 0 bytes. – Anjali Oct 31 '18 at 05:26
  • @Anjali Your request body should have formData not JSON. – Sumesh TG Oct 31 '18 at 05:47
  • @SumeshTG I want both in one request. @RequestPart("json") CampaignCreatorDTO campaignCreatorDTO, @RequestPart("file") MultipartFile adGraphic – Anjali Oct 31 '18 at 06:23
  • @Anjali Ya. It is possible using `ajax` and formData. How you pass data to the server? – Sumesh TG Oct 31 '18 at 06:25
  • Please check updated the question with client code – Anjali Oct 31 '18 at 06:50

2 Answers2

-1

I solved the issue by implementing multipartresolver in configuration.

@Bean
    public MultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }
Anjali
  • 1,623
  • 5
  • 30
  • 50
-1

First way: If you will use postman/javaScript framework -> you have to define media-type of every RequestPart. example in POSTMAN: enter image description here

Second way is implement maintaining of octet-stream, because spring set it by default in AbstractMessageConverterMethodArgumentResolver.class if there is no content-type header in request part. (I'm using spring-boot-starter-parent 2.4.1 -> spring-webmvc 5.3.2) Y

So here is 2 cases I found (to map response JSON to DTO):

1 case (not recommended): Set supporting to JSON converter: enter image description here

2 case: Define new Converter class which will work definitely for needed classes (in my case it is MDVersionDTO.class) and definitely when it comes like octet-stream, to implement it, ovveride canRead() method. enter image description here

Konstantin
  • 117
  • 1
  • 5