'Jackson: Unable to deserialize a map attribute in Request Dto using annotations

I want to deserialize this json as Map<string, LocalizationDto>:

{
    "DE": {
        "name": "name1",
        "description": "name1 description"
    },
    "EN": {
        "name": "name2",
        "description": "name2 description"
    }
}

that represents the parameter "localizations" in this Request Dto:

@Getter
@Setter
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@AllArgsConstructor
public class RequestDto {

    @Size(max = 16)
    @NotEmpty
    private String code;

    @NotNull
    private Boolean stackable;

    @NotNull
    private MultipartFile file;

    
    @JsonDeserialize(using = MapDeserializer.class )
    @JsonProperty("localizations")
    @NotEmpty
    private Map<String, LocalizationDto> localizations;

    @JsonCreator
    public RequestDto() {
    }


    public static class MapDeserializer extends JsonDeserializer <Map<String, LocalizationDto>> {

        public MapDeserializer() {
            super();
        }

        @Override
        public Map<String, LocalizationDto> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
                throws IOException {
            ObjectMapper mapper = (ObjectMapper) jsonParser.getCodec();
            if (jsonParser.getCurrentToken().equals(JsonToken.START_OBJECT)) {
                return mapper.readValue(jsonParser, new TypeReference<>() {
                });
            } else {
                //consume this stream
                mapper.readTree(jsonParser);
                return new HashMap<>();
            }
        }
    }
}

The LocalizationDto class is:

@Getter
@Setter
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@NoArgsConstructor
@AllArgsConstructor
public class LocalizationDto {

    @NotBlank
    @Size(max = 1024)
    public String name;

    @NotBlank
    @Size(max = 1024)
    public String description;
}

the Deserialization should be triggered by this Rest Request:

@PostMapping(value = "/create", consumes = MediaType.MULTIPART_FORM_DATA_VALUE , produces = MediaType.APPLICATION_JSON_VALUE)
    public responseDto createEntity(Authentication authentication,
                                @ModelAttribute @Valid RequestDto requestDto) throws IOException {

        return service.createEntity(requestDto));
    }
}

After running this request I got a problem with the attribut "localizations":

"org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult
default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Map' for property 'localizations';
nested exception is java.lang.IllegalStateException:

It seems that Jackson is not considering my custom deserializer class MapDeserializer or any annotation is missing.

Thank you for the support



Sources

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

Source: Stack Overflow

Solution Source