ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Jackson JSON ↔ DTO 직렬화·역직렬화
    Spring 2025. 8. 12. 19:02

    Jackson이 JSON 데이터를 DTO로 변환하는 규칙은 객체 생성 방법에 따라 달라집니다.

    1. 전체 생성자 (생성자가 하나만 있을 경우)

    • 생성자가 하나뿐이면, @JsonCreator 없이 자동으로 그 생성자를 사용합니다.
    public class User {
        private String name;
        private int age;
    
        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }

     

    2. 전체 생성자 (생성자가 여러 개 있을 경우)

    • 생성자가 여러 개면 Jackson이 어느 생성자를 써야 할지 모르므로 @JsonCreator로 지정합니다.
    • 파라미터 매핑은 @JsonProperty("필드명")으로 지정 (생략하면 파라미터 이름과 JSON 필드명이 동일해야 함, 컴파일 시 -parameters 옵션 필요)
    public class User {
        private String name;
        private int age;
    
        @JsonCreator
        public User(@JsonProperty("name") String name, @JsonProperty("age") int age) {
            this.name = name;
            this.age = age;
        }
    
        public User(String name) {
            this.name = name;
        }
    }

     

    3. 기본 생성자 + Setter

    • 기본 생성자를 호출 → JSON 필드명을 set + 필드명(첫 글자 대문자) 형태의 Setter를 찾아 호출
    • Setter 이름에서 set 제거 후, 첫 글자 소문자로 변환한 이름이 JSON 필드명과 매칭
     
    public class User {
        private String name;
        private int age;
    
        public User() {}
    
        public void setName(String name) { this.name = name; }
        public void setAge(int age) { this.age = age; }
    }

     

    4. public 필드 직접 주입

    • Setter가 없어도 public 필드면 직접 값이 주입됨
    public class User {
        public String name;
        public int age;
    }

     

    5. 역직렬화 안 되는 경우

    • 기본 생성자만 있고 Setter나 전체 생성자가 없는 경우
    • Setter나 전체 생성자가 없고, 필드가 private인 경우
    • 생성자 파라미터 이름과 JSON 필드명이 다르거나, @JsonProperty를 누락한 경우
    • 필드 타입 변환이 불가능한 경우 (예: "abc"를 int에 주입)
    • JSON 필드명과 DTO 필드/Setter 이름이 일치하지 않는 경우

    DTO → JSON (직렬화, Serialization)

    Jackson이 DTO를 JSON으로 변환할 때는 값을 꺼내는 방법이 중요합니다.

    1. Getter 기반 직렬화

    • Getter 메서드에서 get 제거 후 첫 글자를 소문자로 변환한 이름이 JSON 필드명
    • 기본 생성자는 필요 없음 (객체는 이미 존재)
    public class User {
        private String name;
        private int age;
    
        public String getName() { return name; }
        public int getAge() { return age; }
    }

     

    2. public 필드 기반 직렬화

    • Getter가 없어도 public 필드면 해당 필드가 JSON에 포함됨
    public class User {
        public String name;
        public int age;
    }

    3. @JsonProperty로 필드명 변경

    • Getter/필드에 @JsonProperty를 붙이면 JSON 필드명을 강제로 변경 가능
    public class User {
        private String name;
    
        @JsonProperty("username")
        public String getName() { return name; }
    }

    4. @JsonIgnore로 직렬화 제외

    • 특정 필드를 JSON 결과에서 제외하려면 @JsonIgnore 사용
    public class User {
        private String name;
        @JsonIgnore
        private String password;
    
        public String getName() { return name; }
        public String getPassword() { return password; }
    }

     

    5. 직렬화 안 되는 경우

    • Getter가 없고 필드가 private인 경우
    • Getter가 void 반환이거나, 매개변수를 가지는 경우
    • 순환 참조(Circular Reference) 발생 시 → 예외 발생 (해결: @JsonManagedReference / @JsonBackReference / @JsonIgnore)
Designed by Tistory.