'Problem with @ModelAttribute while sending POST method with multipart/form-data

I'm experiencing trouble with multipart data for a reason I don't understand. I can't deserialize a Map.

Below is the Controller:

    @Override
    @PostMapping(value = "/attachments", produces = APPLICATION_JSON_VALUE)
    public ResponseEntity<ResponseInfo> addAttachments(@ModelAttribute AddAttachment request) {
        return new ResponseEntity<>(subscriptionService.addAttachment(request.getSubscriptionIds(), request.getAttachment(), request.getDescription(),
                request.getUserName()), HttpStatus.CREATED);
    }

The AddAttachment class:

    @NotEmpty(message = "The subscription IDs must not be null or empty.") Map<SubscriptionType,
            @NotEmpty(message = "Each list of subscriptions IDs must not be null or empty.")
                    Set<@NotBlank(message = "Each subscription ID must not be null, empty or blank.") String>> subscriptionIds;
    @NotBlank String description;
    @NotBlank String userName;
    @NotBlank MultipartFile attachment;

And, the case on Postman app, put an image: Example on Postman

Value of subscriptionId:

{"DM_SUB": ["WLF1234-123456-12345678","WLF1234-123456-12345679"],
"EI_SUB": ["WLF1234-123456-12345678","WLF1234-123456-12345679"]}

It matches with the enum SubscriptionType And, the error I see:

codes [typeMismatch.addAttachment.subscriptionIds,typeMismatch.subscriptionIds,typeMismatch.java.util.Map,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [addAttachment.subscriptionIds,subscriptionIds]; arguments []; default message [subscriptionIds]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Map' for property 'subscriptionIds'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Map' for property 'subscriptionIds': no matching editors or conversion strategy found]]

I can't find the way to convert this String into Map. Any ideas?



Solution 1:[1]

Finally it work after change the approach.

Controller:

    @PostMapping(value = "/attachments", produces = APPLICATION_JSON_VALUE, consumes = {APPLICATION_JSON_VALUE, MULTIPART_FORM_DATA_VALUE})
    public ResponseEntity<ResponseInfo> addAttachments(@RequestPart @NotBlank AddAttachment request, @RequestPart @NotBlank MultipartFile attachment) {
        return new ResponseEntity<>(alertService.addAttachment(request.getAlertIds(), attachment, request.getDescription(),
                request.getUserName()), HttpStatus.CREATED);
    }

AddAttachment class:

    @NotEmpty(message = "The subscription IDs must not be null or empty.") Map<SubscriptionType,
            @NotEmpty(message = "Each list of subscriptions IDs must not be null or empty.")
                    Set<@NotBlank(message = "Each subscription ID must not be null, empty or blank.") String>> subscriptionIds;
    @NotBlank String description;
    @NotBlank String userName;
    //No multipart file here.

From Postman App side:

New approach from Postman App

Conclusion:

  • Each part could have different content type
  • Separate files from rest of logic (JSon)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 marc_s