Jackson 라이브러리의 @JsonProperty 어노테이션은 JSON 데이터의 속성 이름(property name)을 지정하는 데 사용됩니다. 이 어노테이션은 생성자(constructor) 또는 팩토리 메서드(factory method)의 매개변수에 적용할 수 있으며, @JsonCreator 어노테이션과 함께 사용하면 JSON 문자열을 원하는 방식으로 역직렬화(deserialization)할 수 있습니다.
@JsonCreator는 @JsonSetter를 사용할 수 없는 상황에서 특히 유용합니다. 대표적인 예가 불변(immutable) 객체입니다. 불변 객체에는 setter 메서드가 없기 때문에 초기값을 반드시 생성자를 통해 주입해야 하며, 이때 @JsonCreator가 선언된 생성자나 팩토리 메서드가 역직렬화 과정에서 호출됩니다.
1. @JsonProperty + 생성자(Constructor) 활용
생성자에 @JsonCreator를 선언하고, 각 매개변수에 @JsonProperty를 붙여 JSON 키와 매핑하는 방식입니다. JSON의 키 이름과 자바 필드 이름이 서로 다를 때 특히 유용합니다.
예제 코드
import com.fasterxml.jackson.annotation.*;
import java.io.IOException;
import com.fasterxml.jackson.databind.*;
public class JsonCreatorTest1 {
public static void main(String[] args) throws IOException {
ObjectMapper om = new ObjectMapper();
String jsonString = "{\"id\":\"101\", \"fullname\":\"Ravi Chandra\", \"location\":\"Pune\"}";
System.out.println("JSON: " + jsonString);
Customer customer = om.readValue(jsonString, Customer.class);
System.out.println(customer);
}
}
// Customer 클래스
class Customer {
private String id;
private String name;
private String address;
public Customer() {
}
@JsonCreator
public Customer(
@JsonProperty("id") String id,
@JsonProperty("fullname") String name,
@JsonProperty("location") String address) {
this.id = id;
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]";
}
}실행 결과
JSON: {"id":"101", "fullname":"Ravi Chandra", "location":"Pune"}
Customer [id=101, name=Ravi Chandra, address=Pune]위 예제에서 JSON의 키는 fullname, location이지만, Customer 클래스의 필드 이름은 name, address입니다. 생성자 매개변수에 @JsonProperty로 JSON 키를 지정했기 때문에 이름이 달라도 정상적으로 값이 주입됩니다.
2. @JsonCreator + 팩토리 메서드(Factory Method) 활용
static 팩토리 메서드에 @JsonCreator를 선언하는 방식도 가능합니다. 객체 생성 로직을 캡슐화하거나, 생성 전에 값 검증 등의 추가 처리가 필요한 경우 이 방식이 더 적합합니다.
예제 코드
import com.fasterxml.jackson.annotation.*;
import java.io.IOException;
import com.fasterxml.jackson.databind.*;
public class JsonCreatorTest2 {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String jsonString = "{\"id\":\"102\", \"fullname\":\"Raja Ramesh\", \"location\":\"Hyderabad\"}";
System.out.println("JSON: " + jsonString);
Customer customer = mapper.readValue(jsonString, Customer.class);
System.out.println(customer);
}
}
// Customer 클래스
class Customer {
private String id;
private String name;
private String address;
public Customer() {
}
@JsonCreator
public static Customer createCustomer(
@JsonProperty("id") String id,
@JsonProperty("fullname") String name,
@JsonProperty("location") String address) {
Customer customer = new Customer();
customer.id = id;
customer.name = name;
customer.address = address;
return customer;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]";
}
}실행 결과
JSON: {"id":"102", "fullname":"Raja Ramesh", "location":"Hyderabad"}
Customer [id=102, name=Raja Ramesh, address=Hyderabad]핵심 정리
- @JsonCreator: Jackson에게 역직렬화 시 사용할 생성자 또는 팩토리 메서드를 지정합니다.
- @JsonProperty: JSON의 키 이름과 자바 매개변수를 매핑합니다. JSON 키와 필드 이름이 다를 경우 필수적입니다.
- setter 메서드가 없는 불변 객체나, JSON 구조와 객체 구조가 일치하지 않는 경우에 @JsonCreator 방식이 가장 효과적입니다.