[Java] ObjectMapper (2) TypeReference, 설정메서드, 어노테이션
* TypeReference<T>
Jackson의 ObjectMapper에서 제공하는 클래스로
역직렬화(deserialization) 과정에서 제네릭 타입 정보를 전달하기 위해 사용.
** 단일 객체가 아닌 복잡한 타입인 경우, 런타임에 타입 정보가 사라지기 때문에 명시적으로 타입을 전달해줘야함.
List<User>, Map<String, User>, List<Map<String, User>>
JSON 문자열 --> List<Object>
String json = "[{\"name\":\"phyho\",\"age\":10}]";
List<User> users = mapper.readValue(json, new TypeReference<List<User>>() {});
JSON 문자열 --> Map<String, Object>
String json = "{\"name\":\"phyho\", \"age\":10}";
Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
(중첩형태)
String json = "{\"user1\":{\"name\":\"phyho\",\"age\":10}}";
Map<String, User> userMap = mapper.readValue(json, new TypeReference<Map<String, User>>() {});
JSON 문자열 --> List<Map<String, Object>>
String json = "[{\"name\":\"phyho\", \"age\":10}, {\"name\":\"pyo\", \"age\":11}]";
List<Map<String, Object>> list =
mapper.readValue(json, new TypeReference<List<Map<String, Object>>>() {});
(중첩형태)
String json = """
{
"groupA": [
{ "name": "phyho", "age": 10 },
{ "name": "pyo", "age": 11 }
],
"groupB": [
{ "name": "phyho", "age": 10 }
]
}
""";
Map<String, List<User>> userGroups =
mapper.readValue(json, new TypeReference<Map<String, List<User>>>() {});
* ObjectMapper 설정 메서드
해당 objectMapper가 처리하는 모든 객체에 전역으로 적용할 설정 세팅.
.enable(Feature) / .disable(Feature)
기능을 켜는/끄는 메소드
.configure(Feature, boolean)
.configure(Feature, true) => .enable(Feature)
.configure(Feature, false) => . disable (Feature)
* Feature
SerializationFeature : Java → JSON 직렬화 설정
WRITE_DATES_AS_TIMESTAMPS
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
=> 날짜를 문자열로 출력
INDENT_OUTPUT
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
=> JSON을 보기 좋은 형태로 출력.
DeserializationFeature : JSON → Java 역직렬화 설정
FAIL_ON_UNKNOWN_PROPERTIES
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
=> JSON에 없는 필드 무시
ACCEPT_EMPTY_STRING_AS_NULL_OBJECT
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
=> 비어있는 문자열을 null로 처리
MapperFeature : 매핑 방식 설정 (전반)
INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES
mapper.enable(MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES);
=> @JsonCreator 없이도 생성자 사용 허용.
* Jackson 어노테이션
필드별로 설정 다르게 지정.
(클래스)
@JsonIgnoreProperties(ignoreUnknown = true)
JSON에는 있지만 Java 클래스에 정의되어 있지 않은 필드는 무시하고 역직렬화 진행.
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private String name;
private int age;
// getter, setter
}
{
"name": "phyho",
"age": 10,
"extraField": "extraField"
}
=> extraField는 User클래스에 없지만 에러없이 역직렬화.
@JsonIgnoreProperties({"field1", "field2"})
Java 클래스에 정의되어 있지만 제외하고 직렬화/역직렬화 진행.
@JsonIgnoreProperties({"password"})
public class User {
private String name;
private String password;
}
=> 직렬화 시 JSON에 password를 미포함.
=> 역직렬화 시 JSON에 password가 있어도 무시하고 진행.
@JsonInclude
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private String name;
private String nickname;
}
=> 직렬화 시 null인 경우 JSON에 미포함.
- ALWAYS : 항상 포함. (기본값, null 포함)
- NON_NULL : null인 경우 제외.
- NON_EMPTY : null, 빈 값 제외. " ", [], {}
- NON_DEFAULT : 기본값이면 제외 숫자 0, boolean false, 객체 기본 생성값
(필드)
@JsonIgnore
public class User {
private String name;
@JsonIgnore
private String password;
}
=> 직렬화/역직렬화 시 password는 JSON에 미포함
@JsonProperty
public class User {
@JsonProperty("full_name")
private String name;
}
=> JSON의 'full_name'을 Java의 'name' 필드와 매핑.
@JsonAlias
public class User {
@JsonAlias({"username", "user_name"})
private String name;
}
=> JSON 의 'username' 이나 'user_name'을 Java의 'name필드와 매핑.
@JsonFormat (날짜 포맷)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime startTime;
=> "startTime": "2025-04-10 14:00" 형태로 출력 가능.