728x90
목차
1. 개요
test code 작성 중 gson 을 사용하다가 데이터 타입인 Instant를 이해하지 못하여 400 에러가 발생하였습니다.
이때 gson이 Instant type을 이해할 수 있도록 직렬화/역직렬화 작업이 필요합니다.
먼저 Gson, GsonBuilder에 대해서 알아보겠습니다.
2. Gson이란?
- java 객체를 json 문법으로 변환해주는 java library 입니다.
- json 문자를 java 객체로 변환하는 것도 제공합니다.
- java 객체 → json 문법으로 변환하는 것을 직렬화(serialization)라고 하고
- json 문법 → java 객체로 변환하는 것을 역직렬화(deserialization)라고 부릅니다.
3. GsonBuilder
Gson 클래스에는 객체를 json 형식으로 직렬화 하기 위해 다양한 메소드를 제공하고있습니다.
GsonBuilder library에서 제공하고 있는 직렬화/역직렬화 옵션을 설정해서 Gson 객체를 생성해주는 기능을 제공합니다.
프로젝트 내에서 이용할 직렬화 옵션이 공통적으로 적용될 것이라면 static으로 생성하여 활용하는 것도 좋습니다.
→ 보통 GsonUtils에 공통 옵션들을 설정하여 사용합니다.
4. Instant Deserializer
- gson이 Instant type을 이해할 수 있도록 Deserialization 메소드를 구현하여
- GsonBuilder 생성 시 registerTypeAdapter() 메소드에 옵션으로 설정해줍니다.
예시코드
...
/**
* then
*/
val response = result.andExpect(MockMvcResultMatchers.status().isOk).andReturn().response
val gson = GsonBuilder()
.registerTypeAdapter(Instant::class.java, InstantDeserializer()) //옵션으로 설정!!
.create()
val testResponse = gson.fromJson(response.contentAsString, TestResponseV1::class.java)
assertEquals(2, testResponse.items.size)
assertEquals(testResponse.price, 2)
//deserializer
class InstantDeserializer : JsonDeserializer<Instant?>, Type {
@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type?, context: JsonDeserializationContext?): Instant {
return Instant.parse(json.asString)
}
}
5. Localdate Serializer
- deserializer와 마찬가지로 gson이 Localdate type 을 이해 할 수 있도록 Serializer 메소드를 구현한뒤
- GsonBuilder 생성 시 registerTypeAdapter() method에 옵션값으로 설정해줍니다.
- LocalDateTime의 경우 field 명에 JsonFormat을 정의해주어야 gson에서도 이해합니다.
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private final LocalDateTime localDateTime;
예시코드
/**
* when
*/
val url = "/users/{userId}"
val gson: Gson = GsonBuilder()
.registerTypeAdapter(LocalDate::class.java, LocalDateSerializer()) //option으로 설정!!
.create()
val payloadJsonObject = JSONObject(gson.toJson(testRequest))
class LocalDateSerializer : JsonSerializer<LocalDate?>, Type {
override fun serialize(
localDate: LocalDate?,
srcType: Type?,
context: JsonSerializationContext?
): JsonElement {
return JsonPrimitive(DateTimeFormatter.ISO_DATE.format(localDate))
}
}
6. 참고자료
https://velog.io/@leverest96/%EB%B0%94%EB%B3%B4%EA%B0%99%EC%9D%80-gson%EC%97%90%EA%B2%8C-LocalDate%EB%82%98-LocalDateTime-%EC%95%8C%EB%A0%A4%EC%A3%BC%EA%B8%B0
https://blog.jiniworld.me/158
728x90
'스터디 > JAVA' 카테고리의 다른 글
[Nginx] Server Keepalive와 Upstream Keepalive (0) | 2025.01.26 |
---|---|
[Nginx] underscore 가 포함된 custom header 확인이 안 될 경우(underscores_in_headers) (0) | 2025.01.25 |
[JAVA] 타임존 알아보기 Instant, LocalDateTime, ZonedDateTime (0) | 2024.07.02 |
[JAVA] enum 비교는 equals 일까 == 일까? (1) | 2024.04.28 |
[JAVA] Junit InvalidTestClassError 오류 원인과 해결 방법 (0) | 2024.01.29 |