@JsonUnwrapped 어노테이션은 Jackson 라이브러리에서 직렬화(Serialization)와 역직렬화(Deserialization) 과정 중에 값을 언래핑(unwrapping)하기 위해 사용됩니다. 이 어노테이션을 활용하면 내부에 포함된(composed) 클래스의 필드 값들이 마치 부모 클래스 자체의 속성인 것처럼 평면적으로(flat) 렌더링됩니다.
쉽게 말해, 객체 안에 또 다른 객체가 중첩되어 있을 때 @JsonUnwrapped를 적용하면 JSON 출력 시 중첩 구조 없이 모든 필드가 한 단계로 펼쳐져 표현됩니다. 이는 API 응답을 간결하게 설계하거나 기존 JSON 스키마와의 호환성을 유지해야 할 때 매우 유용합니다.
문법(Syntax)
@Target(value={ANNOTATION_TYPE,FIELD,METHOD,PARAMETER})
@Retention(value=RUNTIME)
public @interface JsonUnwrapped예제 코드
아래 예제에서는 Employee 클래스 내부에 Address 객체를 포함시키고, @JsonUnwrapped를 적용하여 직렬화 결과를 확인합니다.
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
public class JsonUnwrappedAnnotationTest {
public static void main(String args[]) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(new Employee());
System.out.println(jsonString);
}
}
class Employee {
public int empId = 110;
public String empName = "Raja Ramesh";
@JsonUnwrapped
public Address address = new Address();
// Address 클래스
public static class Address {
public String doorNumber = "1118";
public String street = "madhapur";
public String pinCode = "500081";
public String city = "Hyderabad";
}
}실행 결과(Output)
Address 객체가 별도의 중첩 JSON 객체로 출력되지 않고, 부모 클래스인 Employee의 필드들과 동일한 계층에서 펼쳐져 출력되는 것을 확인할 수 있습니다.
{
"empId" : 110,
"empName" : "Raja Ramesh",
"doorNumber" : "1118",
"street" : "madhapur",
"pinCode" : "500081",
"city" : "Hyderabad"
}참고 사항
- prefix / suffix 옵션:
@JsonUnwrapped(prefix = "addr.", suffix = "")형태로 접두사나 접미사를 지정하여 펼쳐진 필드 이름에 규칙을 부여할 수 있습니다. - 적용 대상: 필드(Field), 메서드(Method), 생성자 파라미터(Parameter), 그리고 다른 어노테이션 타입(Annotation Type)에 적용 가능합니다.
- 주의점: Map 타입이나 상속 구조에서는 정상적으로 동작하지 않을 수 있으므로, POJO 기반의 명확한 클래스 구조에서 사용하는 것이 권장됩니다.