👩🏻💻 Programming/SpringBoot
@JsonUnwrapped의 개념과 사용법
한국의 메타몽
2022. 3. 7. 19:26
JsonUnwrapped란?
객체 내부의 프로퍼티(Property), 다시말해 객체 내부의 변수가 unwrapped 상태로 직렬화가 이루어져야할때 사용되는 어노테이션이다.
이해하기 쉽게 아래 예시를 봐보자.
Department.java
package com.logicbig.example;
public class Department {
private String deptName;
private String location;
.............
}
Employee.java
package com.logicbig.example;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
public class Employee {
private String name;
@JsonUnwrapped
private Department dept;
.............
}
Main.java
public class ExampleMain {
public static void main(String[] args) throws IOException {
Department dept = new Department();
dept.setDeptName("Admin");
dept.setLocation("NY");
Employee employee = new Employee();
employee.setName("Amy");
employee.setDept(dept);
System.out.println("-- before serialization --");
System.out.println(employee);
System.out.println("-- after serialization --");
ObjectMapper om = new ObjectMapper();
String jsonString = om.writeValueAsString(employee);
System.out.println(jsonString);
System.out.println("-- after deserialization --");
Employee employee2 = om.readValue(jsonString, Employee.class);
System.out.println(employee2);
}
}
+ @JsonUnwrapped가 사용된 상태의 직렬화 / 역직렬화
-- before serialization --
Employee{name='Amy', dept=Department{deptName='Admin', location='NY'}}
-- after serialization --
{"name":"Amy","deptName":"Admin","location":"NY"}
-- after deserialization --
Employee{name='Amy', dept=Department{deptName='Admin', location='NY'}}
중간부분을 확인해보면 Department가 unwrapped 상태로 직렬화 됐다.
+ @JsonUnwrapped가 사용되지 않은 상태로 직렬화 / 역직렬화
-- before serialization --
Employee{name='Amy', dept=Department{deptName='Admin', location='NY'}}
-- after serialization --
{"name":"Amy","dept":{"deptName":"Admin","location":"NY"}}
-- after deserialization --
Employee{name='Amy', dept=Department{deptName='Admin', location='NY'}}
보다시피 어떤 방법으로든 Department가 unwrapped되지 않았다.
실제 사용 예시
JUnit을 통해 API의 Response를 테스트 하던 중, 아래와 같은 에러가 발생했다.
19:16:21.306 [Test worker] ERROR c.h.i.a.p.내가테스트중인.대상 - server error(Type definition error: [simple type, class 내가테스트중인DTO$ResponseBody]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class 내가테스트중인DTO$ResponseBody and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: 내가테스트중인DTO$Response["body"]))
* 개인정보는 임의로 이름을 변경
No serializer found for class, no properties discovered to create BeanSerializer 에러가 발생했는데,
이유인 즉슨 말 그대로 No serializer, 다시말해 직렬화 된 데이터가 없어서 데이터를 읽어들이는데 실패해서 발생한 에러였다.
@Builder
@AllArgsConstructor
public static class ResponseBody {
private long totalUseCount;
@JsonUnwrapped
private List<MultipleUseDto> results;
...
위와 같이 직렬화가 필요한 대상에게 @JsonUnwrapped를 추가해줬더니 에러가 사라지고 테스트 코드가 정상적으로 작동했다
참고 자료
- LOGICBIG - @JsonUnwrapped