DTO에 담겨있는 LocalDateTime을 직렬화 하지 않고 그냥 ResponseBody에 넣어버리니 다음과 같이 list 형식으로 넘어가버리더라.
이를 해결하기 위해 CustomLocalDateTimeSerializer를 제작하고 Server에서 문자열에서 포메팅해 Discord bot으로 넘겨주는 로직을 작성했다.
DTO
package study.surviveoutsidethejunglespring.algorithm.dto;
import static study.surviveoutsidethejunglespring.config.JacksonConfig.*;
import java.time.LocalDateTime;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import study.surviveoutsidethejunglespring.algorithm.entity.Algorithm;
import study.surviveoutsidethejunglespring.guild.entity.Guild;
@Getter
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AlgorithmTypeDto {
private Long guildInfoId;
private Long algorithmForumId;
@JsonSerialize(using = CustomLocalDateTimeSerializer.class)
private LocalDateTime registrationAt;
private String algorithmType;
public static AlgorithmTypeDto of(Algorithm algorithm, Guild guild) {
return AlgorithmTypeDto.builder()
.guildInfoId(guild.getGuildInfoId())
.algorithmForumId(guild.getAlgorithmForumId())
.registrationAt(algorithm.getRegistrationAt())
.algorithmType(algorithm.getAlgorithmType())
.build();
}
}
JacksonConfig
package study.surviveoutsidethejunglespring.config;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
SimpleModule module = new SimpleModule();
module.addSerializer(LocalDateTime.class, new CustomLocalDateTimeSerializer());
return Jackson2ObjectMapperBuilder.json()
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.modules(new JavaTimeModule(), module)
.build();
}
public static class CustomLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 EEEE", Locale.KOREAN);
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value != null) {
gen.writeString(formatter.format(value));
}
}
}
}
왜 이런 문제가 발생하나 알아봤더니
LocalDateTime을 ResponseBody로 전달할 때, Jackson과 같은 JSON 직렬화 라이브러리가 LocalDateTime을 직렬화할 때 기본적으로 리스트(배열) 형식으로 변환하기 때문이란다. LocalDateTime은 복잡한 시간 정보를 포함하고 있어서, Jackson은 이를 [year, month, day, hour, minute, second, nanosecond]와 같은 배열로 전달한다.
결론!
결포메팅은 서버에서!
'코딩딩 > Error' 카테고리의 다른 글
mongoose save 무한 freezed (0) | 2024.10.10 |
---|---|
IntelliJ Testcode에서 lombok 안먹힐때 (0) | 2024.08.16 |
옵시디언 vim 모드 사용시 줄 바꿈 문제 (1) | 2024.05.21 |
RestController에서 @AuthenticationPrincipal UserDetails principal 정보가 담기지 않은 문제 (0) | 2024.01.12 |
Thymeleaf 사용시 redirect가 동작하지 않는 오류 (1) | 2024.01.10 |