관리 메뉴

나만을 위한 블로그

[Android] SerializedName이란? 본문

Android

[Android] SerializedName이란?

참깨빵위에참깨빵_ 2024. 2. 8. 19:38
728x90
반응형

레트로핏을 쓰면서 보통 Gson도 같이 사용하는데, 이유는 서버에서 받은 JSON 데이터를 앱에서 사용하려면 Boolean, String 등의 타입으로 바꿔야 하기 때문이다.

이것을 서버는 데이터(객체)를 JSON으로 직렬화해서 앱(클라이언트)으로 보내고, 앱은 이 데이터를 역직렬화해서 적절한 타입으로 변환해 사용한다고 볼 수 있다. 이 때 JSON은 String 형태기 때문에 JSON String이라고 부르기도 한다.

직렬화, 역직렬화에 대해선 아래 포스팅을 참고한다.

 

https://onlyfor-me-blog.tistory.com/494

 

직렬화(Serialization), 역직렬화(Deserialization)란?

인텐트로 객체를 넘길 때 직렬화라는 걸 사용해서 넘겼던 적이 있다. 예제 코드도 구글에 많이 있어서 그냥 썼었는데, 직렬화라는 용어 자체를 잘 모르는 채 썼기 때문에 공부하고 포스팅하려고

onlyfor-me-blog.tistory.com

 

결론부터 말하자면, @SerializedName이 무엇이고 왜 쓰는지는 아래와 같다.

 

  • 서버에서 받은 데이터를 data class에 담는 역직렬화 과정에서 필드 이름 매핑을 명시적으로 제공하기 위해 사용
  • Gson 라이브러리에 포함돼 있음
  • JSON 안에서 어노테이션에 지정된 이름과 일치하는 key의 value를 찾은 다음, 그 value를 변수의 타입에 맞게 자동으로 변환해서 변수에 할당

이제 왜 이런 결론이 나오는지 확인한다.

 

서버에서 JSON을 받으려고 하는데, 받을 JSONObject는 이름이 없는 형태며 name, age라는 key가 존재하고 각각 김철수, 10이라는 value가 존재한다고 가정한다. 정리하면 아래와 같은 형태가 될 것이다.

 

{
    "name":"김철수",
    "age":10
}

 

이 데이터를 앱에서 받기 위해 보통 아래와 같이 data class를 구성한다.

 

data class Person(
    val name: String?,
    val age: Int?,
)

 

그러나 이렇게만 작성해선 레트로핏을 통해 받은 JSON 안의 value들이 변수들에 담기지 않는다.

왜냐면 서버로부터 직렬화된 데이터를 받긴 했지만, 그것을 풀어서 name과 age 변수에 넣는 역직렬화 처리가 없기 때문이다.

이 때 @Serialized를 사용한다.

 

import com.google.gson.annotations.SerializedName

data class Person(
    @SerializedName("name")
    val name: String?,
    @SerializedName("age")
    val age: Int?,
)

 

이제 JSON 안의 name, age라는 key의 value들은 data class 안의 name, age 변수로 들어간다.

추가로 @SerializedName 안에 쓰는 이름은 서버에서 전달하는 JSON 안의 key를 토씨 하나 안 틀리고 쓰되, 변수명은 내 마음대로 바꿔도 된다.

@SerializedName 안의 이름과 일치하는 key를 JSON 안에서 찾아야 하는데 이상한 이름을 써 두면 못 찾는 건 당연하다. 반면 data class의 변수명은 서버가 알 필요 없는 것이고, 앱에서만 사용되기 때문에 반드시 서버에서 받는 key와 일치할 필요가 없다. 그래서 아래와 같이 작성해도 된다.

 

import com.google.gson.annotations.SerializedName

data class Person(
    @SerializedName("name")
    val userName: String?,
    @SerializedName("age")
    val userAge: Int?,
)

 

반응형
Comments