1. 직렬화를 위해서는 각 인스턴스 변수에 대한 Getter 메소드가 포함되어 있거나
각 인스턴스 변수에 @JsonProperty 가 명시되어 있어야 한다.
이는 택1로 적용하면 된다.
2. 역직렬화를 위해서는 기본생성자가 반드시 필요하다.
각 인스턴스 변수에 대한 Setter 메소드가 필수로 필요하진 않지만 존재한다면 그것을 활용한다.
3. 일반적으로 ObjectMapper 는 기본으로 쓰지 않고 아래와 같이 재정의해서
프로젝트에서 static 메소드로 사용한다.
public class ObjectMapperUtils {
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.registerModule(new JavaTimeModule());
mapper.setSerializationInclusion(Include.NON_EMPTY);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
}
public static String serialization(Object object) throws JsonProcessingException {
return mapper.writeValueAsString(object);
}
public static <T> T deserialization(String jsonText, Class<T> valueType) throws JsonProcessingException {
return (T) mapper.readValue(jsonText, valueType);
}
public static <T> T typeConvert(Object object, Class<T> convertType){
return (T) mapper.convertValue(object, convertType);
}
}
mapper.registerModule(new JavaTimeModule());
이 설정이 없으면 java8 LocalDateTime 이 직렬화/역직렬화 되지 않는다.
LocalDateTime 변환을 위해서는 해당 클래스의 변수에 @JsonFormat 도 함께 설정해야 한다.
이 설정이 없으면 @JsonFormat 가 재대로 동작하지 않는다.
참고로 위에서 재정의한 ObjectMapper 가 사용되지 않는 Spring Controller 에서
LocalDateTime 을 역직렬화 하고 싶다면 아래와 같이 @DateTimeFormat 을 지정해야 한다.
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
mapper.setSerializationInclusion(Include.NON_EMPTY);
객체를 직렬화할 때 null이나 빈값은 항목에 포함하지 않는다.
즉, 객체에 포함된 변수 중 null 이거나 빈값은 json 변환에 포함되지 않는다.
Default 는 null 이거나 빈값이어도 무조건 json 변환에 포함된다.
클래스에 선언하는 @JsonInclude(JsonInclude.Include.NON_EMPTY) 과 동일한 역할을 한다.
그런데 실무에서는 잘 사용하지 않는다. 대부분 null 이라도 포맷을 그대로 받아서 확인하길 원한다.
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
json 문자열을 역직렬화할 때 클래스 변수에 매핑되지 않는 없는 키값이 있어도
에러 없이 무시하고 진행한다. Default 는 이 경우 Exception을 발생시킨다.
json 포맷을 엄격하게 지켜야 하는 경우 설정하지 말아야겠지만
어차피 사용되지 않는 값이기 때문에 로직은 정상 수행되도록 이 설정을 하는 것이 좋다.
클래스에 선언하는 @JsonIgnoreProperties(ignoreUnknown = true) 와 동일한 역할을 한다.
mapper.enable(SerializationFeature.INDENT_OUTPUT);
json 문자열을 콘솔에 출력할 때 포맷팅해서 출력한다.
일반적으로 괄호를 포함한 문자열이 한줄에 모두 표기되는데
적절한 개행과 들여쓰기를 통해 보기좋게 출력해준다.
위에서 한 설정 중 동일한 설정이지만 ObjectMapper 에서 할 수 있는 것도 있고 각 모델 클래스에서 할 수 있는 것도 있는데 기본적으로 양쪽에 모두 해주는 것이 좋다. Spring 같은 프레임워크를 사용하는 환경이라면 해당 클래스가 위에서 재정의한 ObjectMapper 를 통해서만 변환된다는 보장이 없기 때문이다.
만약 각 모델 클래스가 아니라 ObjectMapper 에 직접 해야 하는데 내가 커스텀 한 ObjectMapper 가 사용되지 않는 경우에는 어떻게 하나? 예를 들어 Feign의 경우 body를 serialization, deserialization 할 때 기본적으로 Spring에 포함된 ObjectMapper 를 사용한다. 이때는 아래와 같이 ObjectMapper Bean 팩토리 함수를 재정의하면 된다.
@Bean
public ObjectMapper customObjectMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule())
.setSerializationInclusion(Include.NON_EMPTY)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.enable(SerializationFeature.INDENT_OUTPUT);
}
'Backend > Spring+Boot' 카테고리의 다른 글
@Async 설정 (0) | 2021.07.13 |
---|---|
CircuitBreaker, Resilience4j, RestClient (0) | 2021.07.09 |
@RequestMapping consumes, produces (0) | 2021.07.07 |
SpringBoot Redis Cluster Lettuce 설정 (0) | 2021.05.04 |
SpringBoot embedded Redis Cluster (0) | 2021.05.04 |