알고 쓰는 JacksonObjectMapper의 JavaTimeModule

dojinyou·2023년 12월 10일
0

Java Time과 Jackson Java Time Module

자바 8에는 많은 변화들이 있었고 그 중 하나가 java.time 모듈인데요. 이러한 java time에 대해서 Jackson이라는 자바의 json 변환 라이브러리에서는 JavaTimeModule을 통해 지원하고 있습니다.

이번에는 자바 타임 모듈의 여러 클래스와 jackson의 javaTimeModule이 어떻게 지원(변환)하는 지 함께 알아보겠습니다.

Java Time class와 Json 표현방식

Duration

Duration은 내부적으로 seconds와 nanos를 가지고 있고 이를 .으로 구분하여 숫자형으로 변환합니다.

public final class Duration {
	private final long seconds;
	private final int nanos;
}
{
	"duration": 86400.000000000 // Duration.ofDays(1)
}

Period

Period는 년, 월, 일 데이터를 가지고 있는 클래스이며 ISO 8601의 기간 표현 방식을 문자열로 변환됩니다.

public final class Period {
	private final int years;
	private final int months;
	private final int days;
}
{
	"period": "P1Y1M1D" // Period.of(1,1,1)
}

Instant

InstantDuration과 같이 seconds와 nanos로 구성되어 있고 duration과 동일하게 숫자형태로 변환됩니다. 여기서 중요한 것은 소숫점 9번째 자리까지 표현될 수 있다는 점입니다.

public final class Instant {
	private final long seconds;
    private final int nanos;
}
{
	"instant": 1702218238.385442000 // Instant.now()
}

LocalDate

LocalDate 클래스의 경우에는 Period와 동일하게 years, months, days로 구성되어 있으며 이를 숫자 배열형태로 변환합니다.

public final class LocalDate {
	private final int years;
    private final int months;
    private final int days;
}
{
	"localDate": [2023,12,10]
}

LocalTime

LocalTime 클래스는 hour, minute, second, nano 필드로 구성되어 있으며 이를 숫자 배열형태로 변환합니다.

public final class LocalTime {
	private final byte hour;
    private final byte minute;
    private final byte second;
    private final int nano;
}
{
	"localTime": [23,23,58,385463000]
}

LocalDateTime

LocalDateTime 클래스는 LocalDateLocalTime 타입의 필드를 각각 가지고 있으며 이를 모두 포함하는 하나의 숫자 배열로 변환됩니다.

public final class LocalDateTime {
	private final LocalDate date;
    private final LocalTime time;
}
{
	"localDateTime": [2023,12,10,23,23,58,385469000]
}

OffsetTIme

OffsetTime 클래스는 ZoneOffsetLocalTime 타입의 필드를 각각 가지고 있으며 ZoneOffset 정보는 문자열로, LocalTime 정보는 숫자로 된 배열로 변환됩니다.

public final class OffsetTime {
	private final LocalTime time;
    private final ZoneOffset offset;
}
{
	"offsetTime": [23,23,58,385477000,"+09:00"]
}

OffsetDateTime

OffsetDateTime 클래스는 ZoneOffsetLocalDateTime 타입의 필드를 각각 가지고 있으나 Instant와 동일한 초(second)와 나노초의 형태의 숫자로 변환됩니다.

public final class OffsetTime {
	private final LocalTime time;
    private final ZoneOffset offset;
}
{
	"offsetDateTime": 1702219187.624879000
}

ZoneId

ZoneId 클래스는 추상 실드 클래스로 ZoneOffsetZoneRegion이 상속하고 있습니다. ZoneRegion의 경우 string id를 통해 time zone id를 가지고 있으며 이를 문자열로 변환하고 있습니다.

public abstract sealed class ZoneId permits ZoneOffset, ZoneRegion {
}

final class ZoneRegion extends ZoneId {
	private final String id;
}
{
	"zoneId": "Asia/Seoul"
}

ZoneOffset

ZoneOffset 클래스는 ZoneId를 상속하고 내부적으로 totcalSeconds를 가지고 있으며 이를 문자열로 변환하고 있습니다.

public final class ZoneOffset extends ZoneId {
	private final int totalSeconds;
    private final transient String id;
}
{
	"zoneOffset": "+09:00"
}

ZoneDateTime

ZoneDateTime 클래스는 LocalDateTime, ZoneOffset, ZoneId를 필드로 가지고 있고 변환시에는 초와 나노초로 구성된 숫자로 변환됩니다.

public final class ZonedDateTime {
	private final LocalDateTime dateTime;
    private final ZoneOffset offset;
    private final ZoneId zone;
}
{
	"zonedDateTime": 1702219658.570394000
}

Year

Year 클래스는 year 정보를 int로 가지고 있고 숫자로 변환됩니다.

public final class  Year{
	private final int year;
}
{
	"year": 2023
}

YearMonth

YearMonth 클래스는 year과 month 정보를 int 타입으로 가지고 변환 시에 각각을 포함하는 숫자 배열로 변환됩니다.

public final class YearMonth {
	private final int year;
    private final int month;
}
{
	"yearMonth": [2023,12]
}

MonthDays

MonthDay 클래스는 month와 day 정보를 int 타입으로 가지고 변환 시에 문자열로 변환됩니다.

public final class MonthDay {
	private final int month;
    private final int day;
}
{
	"monthDay": "--12-10"
}

마치며

전체적인 클래스와 전체적인 규칙성을 볼 수도 있었지만 몇몇 변환 형태는 기대와 다를 수 있을 것 같습니다. 필요에 따라서 적절한 커스텀 직렬화/역직렬화 방식을 구현해야할 것 같습니다.

profile
더 좋은 세상을 만드는 데 기술로 기여하고 싶습니다

0개의 댓글