javaspring-boot

How to receive a list of objects on Spring Boot on a multipart request


I have the following route on my API:

@PostMapping(value = "createParnter", consumes = "multipart/form-data")
public ResponseEntity<String> createPartner(
        @ModelAttribute PartnerRequest partnerRequest
) 

The DTOs for the request are the following:

record Contacts(
        String name,
        String email,
) {}

public record PartnerRequest(
        String name,
        MultipartFile logo,
        String link,
        List<Contact> contacts
){}

Sending only the non-list fields via postman, I get a successful request: enter image description here

However, if I try to send the Contact list together, I get some kind of conversion error: "Failed to convert value of type 'java.lang.String' to required type 'java.util.List'; Cannot convert value of type 'java.lang.String' to required type 'com.example.dto.Contacts' for property 'contacts[0]': no matching editors or conversion strategy found"

Example of Contact list JSON:

[{"name": "testName", "email": "testEmail}]

I didn't find anything about sending a list of objects (just files) on SO or places like Reddit, etc. GPT couldn't give any working answer as well


Solution

  • Spring is trying to convert the string [{"name": "testName", "email": "testEmail}] to a contact list List<Contact>, but it doesn't know how to do it. You need to help it do it with a converter:

    @Component
    public class StringToContactListConverter implements Converter<String, List<Contact>> {
    
        private final ObjectMapper objectMapper = new ObjectMapper();
    
        @Override
        public List<Contact> convert(String source) {
            try {
                TypeFactory typeFactory = objectMapper.getTypeFactory();
                CollectionType collectionType = typeFactory.constructCollectionType(List.class, Contact.class);
                return objectMapper.readValue(source, collectionType);
            } catch (JsonProcessingException exception) {
                throw new IllegalArgumentException("Error converting " + source + " to contact list", exception);
            }
        }
    }