Java/공부공부

[Java] ObjectMapper (2) TypeReference, 설정메서드, 어노테이션

phyho 2025. 4. 10. 17:47

 

* 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" 형태로 출력 가능.