API를 통해 아래와 같은 구조의 json 을 받아오고 있고,

{
    "permission": {
        "col1": {
            "name": "컬럼1",
            "authority": true
        },
        "col2": {
            "name": "컬럼2",
            "authority": false
        }
    }
}

 

dto를 이렇게 만들었는데,

@Data
@NoArgsConstructor
public class PermissionDto {
    @JsonProperty("permission")
    private Map<String, PermissionDetail> permission;
 
    @Data
    @NoArgsConstructor
    public static class PermissionDetail {
        @JsonProperty("name")
        private String name;
 
        @JsonProperty("authority")
        private Boolean authority;
    }
}

 

이런 식으로 API에서 빈값을 {} 가 아니라 [] 로 응답한다면,

class MyTest {
    void testMapper() {
        String s = "{\"permission\":{\"col1\":{\"name\":\"컬럼1\",\"authority\":true},\"col2\":[]}}";
        PermissionDto permissionDto = new PermissionDto();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            permissionDto = objectMapper.readValue(s, PermissionDto.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(permissionDto);
    }
}

 

아래와 같은 예외 발생.

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.mytest.MyTest$PermissionDto$PermissionDetail` from Array value (token `JsonToken.START_ARRAY`)
 at [Source: (String)"{"permission":{"col1":{"name":"col1","authority":true},"col2":[]}}"; line: 1, column: 63] (through reference chain: com.mytest.MyTest$PermissionDto["permission"]->java.util.LinkedHashMap["col2"])

 

API 쪽에서 정확하게 형변환을 해서 object {} 타입으로 넘겨주는게 가장 좋겠지만,
이쪽에서 손댈 수 없는 API 라면 받는 쪽에서 번거롭게 처리해줘야 함.
ObjectMapper의 deserialization 설정 중 DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT를 세팅해서,
비어있는 array [] 가 넘어올 경우 null 로 변환해주는 방식을 이용.

class MyTest {
    void testMapper() {
        String s = "{\"permission\":{\"col1\":{\"name\":\"col1\",\"authority\":true},\"col2\":[]}}";
        PermissionDto permissionDto = new PermissionDto();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
        try {
            permissionDto = objectMapper.readValue(s, PermissionDto.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(permissionDto);
    }
}

 

 

[참고]

https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind/latest/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT

 

 

'Java' 카테고리의 다른 글

[Java] GNU gettext를 이용하여 번역 사용 (i18n, l10n)  (0) 2022.07.04
Posted by bloodguy
,